]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/iD/iD.js
Update to iD v2.4.0
[rails.git] / vendor / assets / iD / iD.js
1 (function () {
2 function actionAddEntity(way) {
3     return function(graph) {
4         return graph.replace(way);
5     };
6 }
7
8 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
9
10
11
12
13
14 function createCommonjsModule(fn, module) {
15         return module = { exports: {} }, fn(module, module.exports), module.exports;
16 }
17
18 var lodash = createCommonjsModule(function (module, exports) {
19 /**
20  * @license
21  * Lodash <https://lodash.com/>
22  * Copyright JS Foundation and other contributors <https://js.foundation/>
23  * Released under MIT license <https://lodash.com/license>
24  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
25  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
26  */
27 (function() {
28
29   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
30   var undefined;
31
32   /** Used as the semantic version number. */
33   var VERSION = '4.17.4';
34
35   /** Used as the size to enable large array optimizations. */
36   var LARGE_ARRAY_SIZE = 200;
37
38   /** Error message constants. */
39   var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
40       FUNC_ERROR_TEXT = 'Expected a function';
41
42   /** Used to stand-in for `undefined` hash values. */
43   var HASH_UNDEFINED = '__lodash_hash_undefined__';
44
45   /** Used as the maximum memoize cache size. */
46   var MAX_MEMOIZE_SIZE = 500;
47
48   /** Used as the internal argument placeholder. */
49   var PLACEHOLDER = '__lodash_placeholder__';
50
51   /** Used to compose bitmasks for cloning. */
52   var CLONE_DEEP_FLAG = 1,
53       CLONE_FLAT_FLAG = 2,
54       CLONE_SYMBOLS_FLAG = 4;
55
56   /** Used to compose bitmasks for value comparisons. */
57   var COMPARE_PARTIAL_FLAG = 1,
58       COMPARE_UNORDERED_FLAG = 2;
59
60   /** Used to compose bitmasks for function metadata. */
61   var WRAP_BIND_FLAG = 1,
62       WRAP_BIND_KEY_FLAG = 2,
63       WRAP_CURRY_BOUND_FLAG = 4,
64       WRAP_CURRY_FLAG = 8,
65       WRAP_CURRY_RIGHT_FLAG = 16,
66       WRAP_PARTIAL_FLAG = 32,
67       WRAP_PARTIAL_RIGHT_FLAG = 64,
68       WRAP_ARY_FLAG = 128,
69       WRAP_REARG_FLAG = 256,
70       WRAP_FLIP_FLAG = 512;
71
72   /** Used as default options for `_.truncate`. */
73   var DEFAULT_TRUNC_LENGTH = 30,
74       DEFAULT_TRUNC_OMISSION = '...';
75
76   /** Used to detect hot functions by number of calls within a span of milliseconds. */
77   var HOT_COUNT = 800,
78       HOT_SPAN = 16;
79
80   /** Used to indicate the type of lazy iteratees. */
81   var LAZY_FILTER_FLAG = 1,
82       LAZY_MAP_FLAG = 2,
83       LAZY_WHILE_FLAG = 3;
84
85   /** Used as references for various `Number` constants. */
86   var INFINITY = 1 / 0,
87       MAX_SAFE_INTEGER = 9007199254740991,
88       MAX_INTEGER = 1.7976931348623157e+308,
89       NAN = 0 / 0;
90
91   /** Used as references for the maximum length and index of an array. */
92   var MAX_ARRAY_LENGTH = 4294967295,
93       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
94       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
95
96   /** Used to associate wrap methods with their bit flags. */
97   var wrapFlags = [
98     ['ary', WRAP_ARY_FLAG],
99     ['bind', WRAP_BIND_FLAG],
100     ['bindKey', WRAP_BIND_KEY_FLAG],
101     ['curry', WRAP_CURRY_FLAG],
102     ['curryRight', WRAP_CURRY_RIGHT_FLAG],
103     ['flip', WRAP_FLIP_FLAG],
104     ['partial', WRAP_PARTIAL_FLAG],
105     ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
106     ['rearg', WRAP_REARG_FLAG]
107   ];
108
109   /** `Object#toString` result references. */
110   var argsTag = '[object Arguments]',
111       arrayTag = '[object Array]',
112       asyncTag = '[object AsyncFunction]',
113       boolTag = '[object Boolean]',
114       dateTag = '[object Date]',
115       domExcTag = '[object DOMException]',
116       errorTag = '[object Error]',
117       funcTag = '[object Function]',
118       genTag = '[object GeneratorFunction]',
119       mapTag = '[object Map]',
120       numberTag = '[object Number]',
121       nullTag = '[object Null]',
122       objectTag = '[object Object]',
123       promiseTag = '[object Promise]',
124       proxyTag = '[object Proxy]',
125       regexpTag = '[object RegExp]',
126       setTag = '[object Set]',
127       stringTag = '[object String]',
128       symbolTag = '[object Symbol]',
129       undefinedTag = '[object Undefined]',
130       weakMapTag = '[object WeakMap]',
131       weakSetTag = '[object WeakSet]';
132
133   var arrayBufferTag = '[object ArrayBuffer]',
134       dataViewTag = '[object DataView]',
135       float32Tag = '[object Float32Array]',
136       float64Tag = '[object Float64Array]',
137       int8Tag = '[object Int8Array]',
138       int16Tag = '[object Int16Array]',
139       int32Tag = '[object Int32Array]',
140       uint8Tag = '[object Uint8Array]',
141       uint8ClampedTag = '[object Uint8ClampedArray]',
142       uint16Tag = '[object Uint16Array]',
143       uint32Tag = '[object Uint32Array]';
144
145   /** Used to match empty string literals in compiled template source. */
146   var reEmptyStringLeading = /\b__p \+= '';/g,
147       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
148       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
149
150   /** Used to match HTML entities and HTML characters. */
151   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
152       reUnescapedHtml = /[&<>"']/g,
153       reHasEscapedHtml = RegExp(reEscapedHtml.source),
154       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
155
156   /** Used to match template delimiters. */
157   var reEscape = /<%-([\s\S]+?)%>/g,
158       reEvaluate = /<%([\s\S]+?)%>/g,
159       reInterpolate = /<%=([\s\S]+?)%>/g;
160
161   /** Used to match property names within property paths. */
162   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
163       reIsPlainProp = /^\w*$/,
164       reLeadingDot = /^\./,
165       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
166
167   /**
168    * Used to match `RegExp`
169    * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
170    */
171   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
172       reHasRegExpChar = RegExp(reRegExpChar.source);
173
174   /** Used to match leading and trailing whitespace. */
175   var reTrim = /^\s+|\s+$/g,
176       reTrimStart = /^\s+/,
177       reTrimEnd = /\s+$/;
178
179   /** Used to match wrap detail comments. */
180   var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
181       reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
182       reSplitDetails = /,? & /;
183
184   /** Used to match words composed of alphanumeric characters. */
185   var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
186
187   /** Used to match backslashes in property paths. */
188   var reEscapeChar = /\\(\\)?/g;
189
190   /**
191    * Used to match
192    * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
193    */
194   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
195
196   /** Used to match `RegExp` flags from their coerced string values. */
197   var reFlags = /\w*$/;
198
199   /** Used to detect bad signed hexadecimal string values. */
200   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
201
202   /** Used to detect binary string values. */
203   var reIsBinary = /^0b[01]+$/i;
204
205   /** Used to detect host constructors (Safari). */
206   var reIsHostCtor = /^\[object .+?Constructor\]$/;
207
208   /** Used to detect octal string values. */
209   var reIsOctal = /^0o[0-7]+$/i;
210
211   /** Used to detect unsigned integer values. */
212   var reIsUint = /^(?:0|[1-9]\d*)$/;
213
214   /** Used to match Latin Unicode letters (excluding mathematical operators). */
215   var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
216
217   /** Used to ensure capturing order of template delimiters. */
218   var reNoMatch = /($^)/;
219
220   /** Used to match unescaped characters in compiled string literals. */
221   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
222
223   /** Used to compose unicode character classes. */
224   var rsAstralRange = '\\ud800-\\udfff',
225       rsComboMarksRange = '\\u0300-\\u036f',
226       reComboHalfMarksRange = '\\ufe20-\\ufe2f',
227       rsComboSymbolsRange = '\\u20d0-\\u20ff',
228       rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
229       rsDingbatRange = '\\u2700-\\u27bf',
230       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
231       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
232       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
233       rsPunctuationRange = '\\u2000-\\u206f',
234       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',
235       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
236       rsVarRange = '\\ufe0e\\ufe0f',
237       rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
238
239   /** Used to compose unicode capture groups. */
240   var rsApos = "['\u2019]",
241       rsAstral = '[' + rsAstralRange + ']',
242       rsBreak = '[' + rsBreakRange + ']',
243       rsCombo = '[' + rsComboRange + ']',
244       rsDigits = '\\d+',
245       rsDingbat = '[' + rsDingbatRange + ']',
246       rsLower = '[' + rsLowerRange + ']',
247       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
248       rsFitz = '\\ud83c[\\udffb-\\udfff]',
249       rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
250       rsNonAstral = '[^' + rsAstralRange + ']',
251       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
252       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
253       rsUpper = '[' + rsUpperRange + ']',
254       rsZWJ = '\\u200d';
255
256   /** Used to compose unicode regexes. */
257   var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
258       rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
259       rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
260       rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
261       reOptMod = rsModifier + '?',
262       rsOptVar = '[' + rsVarRange + ']?',
263       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
264       rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
265       rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
266       rsSeq = rsOptVar + reOptMod + rsOptJoin,
267       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
268       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
269
270   /** Used to match apostrophes. */
271   var reApos = RegExp(rsApos, 'g');
272
273   /**
274    * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
275    * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
276    */
277   var reComboMark = RegExp(rsCombo, 'g');
278
279   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
280   var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
281
282   /** Used to match complex or compound words. */
283   var reUnicodeWord = RegExp([
284     rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
285     rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
286     rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
287     rsUpper + '+' + rsOptContrUpper,
288     rsOrdUpper,
289     rsOrdLower,
290     rsDigits,
291     rsEmoji
292   ].join('|'), 'g');
293
294   /** 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/). */
295   var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
296
297   /** Used to detect strings that need a more robust regexp to match words. */
298   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 ]/;
299
300   /** Used to assign default `context` object properties. */
301   var contextProps = [
302     'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
303     'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
304     'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
305     'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
306     '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
307   ];
308
309   /** Used to make template sourceURLs easier to identify. */
310   var templateCounter = -1;
311
312   /** Used to identify `toStringTag` values of typed arrays. */
313   var typedArrayTags = {};
314   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
315   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
316   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
317   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
318   typedArrayTags[uint32Tag] = true;
319   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
320   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
321   typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
322   typedArrayTags[errorTag] = typedArrayTags[funcTag] =
323   typedArrayTags[mapTag] = typedArrayTags[numberTag] =
324   typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
325   typedArrayTags[setTag] = typedArrayTags[stringTag] =
326   typedArrayTags[weakMapTag] = false;
327
328   /** Used to identify `toStringTag` values supported by `_.clone`. */
329   var cloneableTags = {};
330   cloneableTags[argsTag] = cloneableTags[arrayTag] =
331   cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
332   cloneableTags[boolTag] = cloneableTags[dateTag] =
333   cloneableTags[float32Tag] = cloneableTags[float64Tag] =
334   cloneableTags[int8Tag] = cloneableTags[int16Tag] =
335   cloneableTags[int32Tag] = cloneableTags[mapTag] =
336   cloneableTags[numberTag] = cloneableTags[objectTag] =
337   cloneableTags[regexpTag] = cloneableTags[setTag] =
338   cloneableTags[stringTag] = cloneableTags[symbolTag] =
339   cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
340   cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
341   cloneableTags[errorTag] = cloneableTags[funcTag] =
342   cloneableTags[weakMapTag] = false;
343
344   /** Used to map Latin Unicode letters to basic Latin letters. */
345   var deburredLetters = {
346     // Latin-1 Supplement block.
347     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
348     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
349     '\xc7': 'C',  '\xe7': 'c',
350     '\xd0': 'D',  '\xf0': 'd',
351     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
352     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
353     '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
354     '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
355     '\xd1': 'N',  '\xf1': 'n',
356     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
357     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
358     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
359     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
360     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
361     '\xc6': 'Ae', '\xe6': 'ae',
362     '\xde': 'Th', '\xfe': 'th',
363     '\xdf': 'ss',
364     // Latin Extended-A block.
365     '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
366     '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
367     '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
368     '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
369     '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
370     '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
371     '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
372     '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
373     '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
374     '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
375     '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
376     '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
377     '\u0134': 'J',  '\u0135': 'j',
378     '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
379     '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
380     '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
381     '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
382     '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
383     '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
384     '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
385     '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
386     '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
387     '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
388     '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
389     '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
390     '\u0163': 't',  '\u0165': 't', '\u0167': 't',
391     '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
392     '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
393     '\u0174': 'W',  '\u0175': 'w',
394     '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
395     '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
396     '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
397     '\u0132': 'IJ', '\u0133': 'ij',
398     '\u0152': 'Oe', '\u0153': 'oe',
399     '\u0149': "'n", '\u017f': 's'
400   };
401
402   /** Used to map characters to HTML entities. */
403   var htmlEscapes = {
404     '&': '&amp;',
405     '<': '&lt;',
406     '>': '&gt;',
407     '"': '&quot;',
408     "'": '&#39;'
409   };
410
411   /** Used to map HTML entities to characters. */
412   var htmlUnescapes = {
413     '&amp;': '&',
414     '&lt;': '<',
415     '&gt;': '>',
416     '&quot;': '"',
417     '&#39;': "'"
418   };
419
420   /** Used to escape characters for inclusion in compiled string literals. */
421   var stringEscapes = {
422     '\\': '\\',
423     "'": "'",
424     '\n': 'n',
425     '\r': 'r',
426     '\u2028': 'u2028',
427     '\u2029': 'u2029'
428   };
429
430   /** Built-in method references without a dependency on `root`. */
431   var freeParseFloat = parseFloat,
432       freeParseInt = parseInt;
433
434   /** Detect free variable `global` from Node.js. */
435   var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
436
437   /** Detect free variable `self`. */
438   var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
439
440   /** Used as a reference to the global object. */
441   var root = freeGlobal || freeSelf || Function('return this')();
442
443   /** Detect free variable `exports`. */
444   var freeExports = 'object' == 'object' && exports && !exports.nodeType && exports;
445
446   /** Detect free variable `module`. */
447   var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
448
449   /** Detect the popular CommonJS extension `module.exports`. */
450   var moduleExports = freeModule && freeModule.exports === freeExports;
451
452   /** Detect free variable `process` from Node.js. */
453   var freeProcess = moduleExports && freeGlobal.process;
454
455   /** Used to access faster Node.js helpers. */
456   var nodeUtil = (function() {
457     try {
458       return freeProcess && freeProcess.binding && freeProcess.binding('util');
459     } catch (e) {}
460   }());
461
462   /* Node.js helper references. */
463   var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
464       nodeIsDate = nodeUtil && nodeUtil.isDate,
465       nodeIsMap = nodeUtil && nodeUtil.isMap,
466       nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
467       nodeIsSet = nodeUtil && nodeUtil.isSet,
468       nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
469
470   /*--------------------------------------------------------------------------*/
471
472   /**
473    * Adds the key-value `pair` to `map`.
474    *
475    * @private
476    * @param {Object} map The map to modify.
477    * @param {Array} pair The key-value pair to add.
478    * @returns {Object} Returns `map`.
479    */
480   function addMapEntry(map, pair) {
481     // Don't return `map.set` because it's not chainable in IE 11.
482     map.set(pair[0], pair[1]);
483     return map;
484   }
485
486   /**
487    * Adds `value` to `set`.
488    *
489    * @private
490    * @param {Object} set The set to modify.
491    * @param {*} value The value to add.
492    * @returns {Object} Returns `set`.
493    */
494   function addSetEntry(set, value) {
495     // Don't return `set.add` because it's not chainable in IE 11.
496     set.add(value);
497     return set;
498   }
499
500   /**
501    * A faster alternative to `Function#apply`, this function invokes `func`
502    * with the `this` binding of `thisArg` and the arguments of `args`.
503    *
504    * @private
505    * @param {Function} func The function to invoke.
506    * @param {*} thisArg The `this` binding of `func`.
507    * @param {Array} args The arguments to invoke `func` with.
508    * @returns {*} Returns the result of `func`.
509    */
510   function apply(func, thisArg, args) {
511     switch (args.length) {
512       case 0: return func.call(thisArg);
513       case 1: return func.call(thisArg, args[0]);
514       case 2: return func.call(thisArg, args[0], args[1]);
515       case 3: return func.call(thisArg, args[0], args[1], args[2]);
516     }
517     return func.apply(thisArg, args);
518   }
519
520   /**
521    * A specialized version of `baseAggregator` for arrays.
522    *
523    * @private
524    * @param {Array} [array] The array to iterate over.
525    * @param {Function} setter The function to set `accumulator` values.
526    * @param {Function} iteratee The iteratee to transform keys.
527    * @param {Object} accumulator The initial aggregated object.
528    * @returns {Function} Returns `accumulator`.
529    */
530   function arrayAggregator(array, setter, iteratee, accumulator) {
531     var index = -1,
532         length = array == null ? 0 : array.length;
533
534     while (++index < length) {
535       var value = array[index];
536       setter(accumulator, value, iteratee(value), array);
537     }
538     return accumulator;
539   }
540
541   /**
542    * A specialized version of `_.forEach` for arrays without support for
543    * iteratee shorthands.
544    *
545    * @private
546    * @param {Array} [array] The array to iterate over.
547    * @param {Function} iteratee The function invoked per iteration.
548    * @returns {Array} Returns `array`.
549    */
550   function arrayEach(array, iteratee) {
551     var index = -1,
552         length = array == null ? 0 : array.length;
553
554     while (++index < length) {
555       if (iteratee(array[index], index, array) === false) {
556         break;
557       }
558     }
559     return array;
560   }
561
562   /**
563    * A specialized version of `_.forEachRight` for arrays without support for
564    * iteratee shorthands.
565    *
566    * @private
567    * @param {Array} [array] The array to iterate over.
568    * @param {Function} iteratee The function invoked per iteration.
569    * @returns {Array} Returns `array`.
570    */
571   function arrayEachRight(array, iteratee) {
572     var length = array == null ? 0 : array.length;
573
574     while (length--) {
575       if (iteratee(array[length], length, array) === false) {
576         break;
577       }
578     }
579     return array;
580   }
581
582   /**
583    * A specialized version of `_.every` for arrays without support for
584    * iteratee shorthands.
585    *
586    * @private
587    * @param {Array} [array] The array to iterate over.
588    * @param {Function} predicate The function invoked per iteration.
589    * @returns {boolean} Returns `true` if all elements pass the predicate check,
590    *  else `false`.
591    */
592   function arrayEvery(array, predicate) {
593     var index = -1,
594         length = array == null ? 0 : array.length;
595
596     while (++index < length) {
597       if (!predicate(array[index], index, array)) {
598         return false;
599       }
600     }
601     return true;
602   }
603
604   /**
605    * A specialized version of `_.filter` for arrays without support for
606    * iteratee shorthands.
607    *
608    * @private
609    * @param {Array} [array] The array to iterate over.
610    * @param {Function} predicate The function invoked per iteration.
611    * @returns {Array} Returns the new filtered array.
612    */
613   function arrayFilter(array, predicate) {
614     var index = -1,
615         length = array == null ? 0 : array.length,
616         resIndex = 0,
617         result = [];
618
619     while (++index < length) {
620       var value = array[index];
621       if (predicate(value, index, array)) {
622         result[resIndex++] = value;
623       }
624     }
625     return result;
626   }
627
628   /**
629    * A specialized version of `_.includes` for arrays without support for
630    * specifying an index to search from.
631    *
632    * @private
633    * @param {Array} [array] The array to inspect.
634    * @param {*} target The value to search for.
635    * @returns {boolean} Returns `true` if `target` is found, else `false`.
636    */
637   function arrayIncludes(array, value) {
638     var length = array == null ? 0 : array.length;
639     return !!length && baseIndexOf(array, value, 0) > -1;
640   }
641
642   /**
643    * This function is like `arrayIncludes` except that it accepts a comparator.
644    *
645    * @private
646    * @param {Array} [array] The array to inspect.
647    * @param {*} target The value to search for.
648    * @param {Function} comparator The comparator invoked per element.
649    * @returns {boolean} Returns `true` if `target` is found, else `false`.
650    */
651   function arrayIncludesWith(array, value, comparator) {
652     var index = -1,
653         length = array == null ? 0 : array.length;
654
655     while (++index < length) {
656       if (comparator(value, array[index])) {
657         return true;
658       }
659     }
660     return false;
661   }
662
663   /**
664    * A specialized version of `_.map` for arrays without support for iteratee
665    * shorthands.
666    *
667    * @private
668    * @param {Array} [array] The array to iterate over.
669    * @param {Function} iteratee The function invoked per iteration.
670    * @returns {Array} Returns the new mapped array.
671    */
672   function arrayMap(array, iteratee) {
673     var index = -1,
674         length = array == null ? 0 : array.length,
675         result = Array(length);
676
677     while (++index < length) {
678       result[index] = iteratee(array[index], index, array);
679     }
680     return result;
681   }
682
683   /**
684    * Appends the elements of `values` to `array`.
685    *
686    * @private
687    * @param {Array} array The array to modify.
688    * @param {Array} values The values to append.
689    * @returns {Array} Returns `array`.
690    */
691   function arrayPush(array, values) {
692     var index = -1,
693         length = values.length,
694         offset = array.length;
695
696     while (++index < length) {
697       array[offset + index] = values[index];
698     }
699     return array;
700   }
701
702   /**
703    * A specialized version of `_.reduce` for arrays without support for
704    * iteratee shorthands.
705    *
706    * @private
707    * @param {Array} [array] The array to iterate over.
708    * @param {Function} iteratee The function invoked per iteration.
709    * @param {*} [accumulator] The initial value.
710    * @param {boolean} [initAccum] Specify using the first element of `array` as
711    *  the initial value.
712    * @returns {*} Returns the accumulated value.
713    */
714   function arrayReduce(array, iteratee, accumulator, initAccum) {
715     var index = -1,
716         length = array == null ? 0 : array.length;
717
718     if (initAccum && length) {
719       accumulator = array[++index];
720     }
721     while (++index < length) {
722       accumulator = iteratee(accumulator, array[index], index, array);
723     }
724     return accumulator;
725   }
726
727   /**
728    * A specialized version of `_.reduceRight` for arrays without support for
729    * iteratee shorthands.
730    *
731    * @private
732    * @param {Array} [array] The array to iterate over.
733    * @param {Function} iteratee The function invoked per iteration.
734    * @param {*} [accumulator] The initial value.
735    * @param {boolean} [initAccum] Specify using the last element of `array` as
736    *  the initial value.
737    * @returns {*} Returns the accumulated value.
738    */
739   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
740     var length = array == null ? 0 : array.length;
741     if (initAccum && length) {
742       accumulator = array[--length];
743     }
744     while (length--) {
745       accumulator = iteratee(accumulator, array[length], length, array);
746     }
747     return accumulator;
748   }
749
750   /**
751    * A specialized version of `_.some` for arrays without support for iteratee
752    * shorthands.
753    *
754    * @private
755    * @param {Array} [array] The array to iterate over.
756    * @param {Function} predicate The function invoked per iteration.
757    * @returns {boolean} Returns `true` if any element passes the predicate check,
758    *  else `false`.
759    */
760   function arraySome(array, predicate) {
761     var index = -1,
762         length = array == null ? 0 : array.length;
763
764     while (++index < length) {
765       if (predicate(array[index], index, array)) {
766         return true;
767       }
768     }
769     return false;
770   }
771
772   /**
773    * Gets the size of an ASCII `string`.
774    *
775    * @private
776    * @param {string} string The string inspect.
777    * @returns {number} Returns the string size.
778    */
779   var asciiSize = baseProperty('length');
780
781   /**
782    * Converts an ASCII `string` to an array.
783    *
784    * @private
785    * @param {string} string The string to convert.
786    * @returns {Array} Returns the converted array.
787    */
788   function asciiToArray(string) {
789     return string.split('');
790   }
791
792   /**
793    * Splits an ASCII `string` into an array of its words.
794    *
795    * @private
796    * @param {string} The string to inspect.
797    * @returns {Array} Returns the words of `string`.
798    */
799   function asciiWords(string) {
800     return string.match(reAsciiWord) || [];
801   }
802
803   /**
804    * The base implementation of methods like `_.findKey` and `_.findLastKey`,
805    * without support for iteratee shorthands, which iterates over `collection`
806    * using `eachFunc`.
807    *
808    * @private
809    * @param {Array|Object} collection The collection to inspect.
810    * @param {Function} predicate The function invoked per iteration.
811    * @param {Function} eachFunc The function to iterate over `collection`.
812    * @returns {*} Returns the found element or its key, else `undefined`.
813    */
814   function baseFindKey(collection, predicate, eachFunc) {
815     var result;
816     eachFunc(collection, function(value, key, collection) {
817       if (predicate(value, key, collection)) {
818         result = key;
819         return false;
820       }
821     });
822     return result;
823   }
824
825   /**
826    * The base implementation of `_.findIndex` and `_.findLastIndex` without
827    * support for iteratee shorthands.
828    *
829    * @private
830    * @param {Array} array The array to inspect.
831    * @param {Function} predicate The function invoked per iteration.
832    * @param {number} fromIndex The index to search from.
833    * @param {boolean} [fromRight] Specify iterating from right to left.
834    * @returns {number} Returns the index of the matched value, else `-1`.
835    */
836   function baseFindIndex(array, predicate, fromIndex, fromRight) {
837     var length = array.length,
838         index = fromIndex + (fromRight ? 1 : -1);
839
840     while ((fromRight ? index-- : ++index < length)) {
841       if (predicate(array[index], index, array)) {
842         return index;
843       }
844     }
845     return -1;
846   }
847
848   /**
849    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
850    *
851    * @private
852    * @param {Array} array The array to inspect.
853    * @param {*} value The value to search for.
854    * @param {number} fromIndex The index to search from.
855    * @returns {number} Returns the index of the matched value, else `-1`.
856    */
857   function baseIndexOf(array, value, fromIndex) {
858     return value === value
859       ? strictIndexOf(array, value, fromIndex)
860       : baseFindIndex(array, baseIsNaN, fromIndex);
861   }
862
863   /**
864    * This function is like `baseIndexOf` except that it accepts a comparator.
865    *
866    * @private
867    * @param {Array} array The array to inspect.
868    * @param {*} value The value to search for.
869    * @param {number} fromIndex The index to search from.
870    * @param {Function} comparator The comparator invoked per element.
871    * @returns {number} Returns the index of the matched value, else `-1`.
872    */
873   function baseIndexOfWith(array, value, fromIndex, comparator) {
874     var index = fromIndex - 1,
875         length = array.length;
876
877     while (++index < length) {
878       if (comparator(array[index], value)) {
879         return index;
880       }
881     }
882     return -1;
883   }
884
885   /**
886    * The base implementation of `_.isNaN` without support for number objects.
887    *
888    * @private
889    * @param {*} value The value to check.
890    * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
891    */
892   function baseIsNaN(value) {
893     return value !== value;
894   }
895
896   /**
897    * The base implementation of `_.mean` and `_.meanBy` without support for
898    * iteratee shorthands.
899    *
900    * @private
901    * @param {Array} array The array to iterate over.
902    * @param {Function} iteratee The function invoked per iteration.
903    * @returns {number} Returns the mean.
904    */
905   function baseMean(array, iteratee) {
906     var length = array == null ? 0 : array.length;
907     return length ? (baseSum(array, iteratee) / length) : NAN;
908   }
909
910   /**
911    * The base implementation of `_.property` without support for deep paths.
912    *
913    * @private
914    * @param {string} key The key of the property to get.
915    * @returns {Function} Returns the new accessor function.
916    */
917   function baseProperty(key) {
918     return function(object) {
919       return object == null ? undefined : object[key];
920     };
921   }
922
923   /**
924    * The base implementation of `_.propertyOf` without support for deep paths.
925    *
926    * @private
927    * @param {Object} object The object to query.
928    * @returns {Function} Returns the new accessor function.
929    */
930   function basePropertyOf(object) {
931     return function(key) {
932       return object == null ? undefined : object[key];
933     };
934   }
935
936   /**
937    * The base implementation of `_.reduce` and `_.reduceRight`, without support
938    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
939    *
940    * @private
941    * @param {Array|Object} collection The collection to iterate over.
942    * @param {Function} iteratee The function invoked per iteration.
943    * @param {*} accumulator The initial value.
944    * @param {boolean} initAccum Specify using the first or last element of
945    *  `collection` as the initial value.
946    * @param {Function} eachFunc The function to iterate over `collection`.
947    * @returns {*} Returns the accumulated value.
948    */
949   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
950     eachFunc(collection, function(value, index, collection) {
951       accumulator = initAccum
952         ? (initAccum = false, value)
953         : iteratee(accumulator, value, index, collection);
954     });
955     return accumulator;
956   }
957
958   /**
959    * The base implementation of `_.sortBy` which uses `comparer` to define the
960    * sort order of `array` and replaces criteria objects with their corresponding
961    * values.
962    *
963    * @private
964    * @param {Array} array The array to sort.
965    * @param {Function} comparer The function to define sort order.
966    * @returns {Array} Returns `array`.
967    */
968   function baseSortBy(array, comparer) {
969     var length = array.length;
970
971     array.sort(comparer);
972     while (length--) {
973       array[length] = array[length].value;
974     }
975     return array;
976   }
977
978   /**
979    * The base implementation of `_.sum` and `_.sumBy` without support for
980    * iteratee shorthands.
981    *
982    * @private
983    * @param {Array} array The array to iterate over.
984    * @param {Function} iteratee The function invoked per iteration.
985    * @returns {number} Returns the sum.
986    */
987   function baseSum(array, iteratee) {
988     var result,
989         index = -1,
990         length = array.length;
991
992     while (++index < length) {
993       var current = iteratee(array[index]);
994       if (current !== undefined) {
995         result = result === undefined ? current : (result + current);
996       }
997     }
998     return result;
999   }
1000
1001   /**
1002    * The base implementation of `_.times` without support for iteratee shorthands
1003    * or max array length checks.
1004    *
1005    * @private
1006    * @param {number} n The number of times to invoke `iteratee`.
1007    * @param {Function} iteratee The function invoked per iteration.
1008    * @returns {Array} Returns the array of results.
1009    */
1010   function baseTimes(n, iteratee) {
1011     var index = -1,
1012         result = Array(n);
1013
1014     while (++index < n) {
1015       result[index] = iteratee(index);
1016     }
1017     return result;
1018   }
1019
1020   /**
1021    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
1022    * of key-value pairs for `object` corresponding to the property names of `props`.
1023    *
1024    * @private
1025    * @param {Object} object The object to query.
1026    * @param {Array} props The property names to get values for.
1027    * @returns {Object} Returns the key-value pairs.
1028    */
1029   function baseToPairs(object, props) {
1030     return arrayMap(props, function(key) {
1031       return [key, object[key]];
1032     });
1033   }
1034
1035   /**
1036    * The base implementation of `_.unary` without support for storing metadata.
1037    *
1038    * @private
1039    * @param {Function} func The function to cap arguments for.
1040    * @returns {Function} Returns the new capped function.
1041    */
1042   function baseUnary(func) {
1043     return function(value) {
1044       return func(value);
1045     };
1046   }
1047
1048   /**
1049    * The base implementation of `_.values` and `_.valuesIn` which creates an
1050    * array of `object` property values corresponding to the property names
1051    * of `props`.
1052    *
1053    * @private
1054    * @param {Object} object The object to query.
1055    * @param {Array} props The property names to get values for.
1056    * @returns {Object} Returns the array of property values.
1057    */
1058   function baseValues(object, props) {
1059     return arrayMap(props, function(key) {
1060       return object[key];
1061     });
1062   }
1063
1064   /**
1065    * Checks if a `cache` value for `key` exists.
1066    *
1067    * @private
1068    * @param {Object} cache The cache to query.
1069    * @param {string} key The key of the entry to check.
1070    * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1071    */
1072   function cacheHas(cache, key) {
1073     return cache.has(key);
1074   }
1075
1076   /**
1077    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1078    * that is not found in the character symbols.
1079    *
1080    * @private
1081    * @param {Array} strSymbols The string symbols to inspect.
1082    * @param {Array} chrSymbols The character symbols to find.
1083    * @returns {number} Returns the index of the first unmatched string symbol.
1084    */
1085   function charsStartIndex(strSymbols, chrSymbols) {
1086     var index = -1,
1087         length = strSymbols.length;
1088
1089     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1090     return index;
1091   }
1092
1093   /**
1094    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1095    * that is not found in the character symbols.
1096    *
1097    * @private
1098    * @param {Array} strSymbols The string symbols to inspect.
1099    * @param {Array} chrSymbols The character symbols to find.
1100    * @returns {number} Returns the index of the last unmatched string symbol.
1101    */
1102   function charsEndIndex(strSymbols, chrSymbols) {
1103     var index = strSymbols.length;
1104
1105     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1106     return index;
1107   }
1108
1109   /**
1110    * Gets the number of `placeholder` occurrences in `array`.
1111    *
1112    * @private
1113    * @param {Array} array The array to inspect.
1114    * @param {*} placeholder The placeholder to search for.
1115    * @returns {number} Returns the placeholder count.
1116    */
1117   function countHolders(array, placeholder) {
1118     var length = array.length,
1119         result = 0;
1120
1121     while (length--) {
1122       if (array[length] === placeholder) {
1123         ++result;
1124       }
1125     }
1126     return result;
1127   }
1128
1129   /**
1130    * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
1131    * letters to basic Latin letters.
1132    *
1133    * @private
1134    * @param {string} letter The matched letter to deburr.
1135    * @returns {string} Returns the deburred letter.
1136    */
1137   var deburrLetter = basePropertyOf(deburredLetters);
1138
1139   /**
1140    * Used by `_.escape` to convert characters to HTML entities.
1141    *
1142    * @private
1143    * @param {string} chr The matched character to escape.
1144    * @returns {string} Returns the escaped character.
1145    */
1146   var escapeHtmlChar = basePropertyOf(htmlEscapes);
1147
1148   /**
1149    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1150    *
1151    * @private
1152    * @param {string} chr The matched character to escape.
1153    * @returns {string} Returns the escaped character.
1154    */
1155   function escapeStringChar(chr) {
1156     return '\\' + stringEscapes[chr];
1157   }
1158
1159   /**
1160    * Gets the value at `key` of `object`.
1161    *
1162    * @private
1163    * @param {Object} [object] The object to query.
1164    * @param {string} key The key of the property to get.
1165    * @returns {*} Returns the property value.
1166    */
1167   function getValue(object, key) {
1168     return object == null ? undefined : object[key];
1169   }
1170
1171   /**
1172    * Checks if `string` contains Unicode symbols.
1173    *
1174    * @private
1175    * @param {string} string The string to inspect.
1176    * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1177    */
1178   function hasUnicode(string) {
1179     return reHasUnicode.test(string);
1180   }
1181
1182   /**
1183    * Checks if `string` contains a word composed of Unicode symbols.
1184    *
1185    * @private
1186    * @param {string} string The string to inspect.
1187    * @returns {boolean} Returns `true` if a word is found, else `false`.
1188    */
1189   function hasUnicodeWord(string) {
1190     return reHasUnicodeWord.test(string);
1191   }
1192
1193   /**
1194    * Converts `iterator` to an array.
1195    *
1196    * @private
1197    * @param {Object} iterator The iterator to convert.
1198    * @returns {Array} Returns the converted array.
1199    */
1200   function iteratorToArray(iterator) {
1201     var data,
1202         result = [];
1203
1204     while (!(data = iterator.next()).done) {
1205       result.push(data.value);
1206     }
1207     return result;
1208   }
1209
1210   /**
1211    * Converts `map` to its key-value pairs.
1212    *
1213    * @private
1214    * @param {Object} map The map to convert.
1215    * @returns {Array} Returns the key-value pairs.
1216    */
1217   function mapToArray(map) {
1218     var index = -1,
1219         result = Array(map.size);
1220
1221     map.forEach(function(value, key) {
1222       result[++index] = [key, value];
1223     });
1224     return result;
1225   }
1226
1227   /**
1228    * Creates a unary function that invokes `func` with its argument transformed.
1229    *
1230    * @private
1231    * @param {Function} func The function to wrap.
1232    * @param {Function} transform The argument transform.
1233    * @returns {Function} Returns the new function.
1234    */
1235   function overArg(func, transform) {
1236     return function(arg) {
1237       return func(transform(arg));
1238     };
1239   }
1240
1241   /**
1242    * Replaces all `placeholder` elements in `array` with an internal placeholder
1243    * and returns an array of their indexes.
1244    *
1245    * @private
1246    * @param {Array} array The array to modify.
1247    * @param {*} placeholder The placeholder to replace.
1248    * @returns {Array} Returns the new array of placeholder indexes.
1249    */
1250   function replaceHolders(array, placeholder) {
1251     var index = -1,
1252         length = array.length,
1253         resIndex = 0,
1254         result = [];
1255
1256     while (++index < length) {
1257       var value = array[index];
1258       if (value === placeholder || value === PLACEHOLDER) {
1259         array[index] = PLACEHOLDER;
1260         result[resIndex++] = index;
1261       }
1262     }
1263     return result;
1264   }
1265
1266   /**
1267    * Converts `set` to an array of its values.
1268    *
1269    * @private
1270    * @param {Object} set The set to convert.
1271    * @returns {Array} Returns the values.
1272    */
1273   function setToArray(set) {
1274     var index = -1,
1275         result = Array(set.size);
1276
1277     set.forEach(function(value) {
1278       result[++index] = value;
1279     });
1280     return result;
1281   }
1282
1283   /**
1284    * Converts `set` to its value-value pairs.
1285    *
1286    * @private
1287    * @param {Object} set The set to convert.
1288    * @returns {Array} Returns the value-value pairs.
1289    */
1290   function setToPairs(set) {
1291     var index = -1,
1292         result = Array(set.size);
1293
1294     set.forEach(function(value) {
1295       result[++index] = [value, value];
1296     });
1297     return result;
1298   }
1299
1300   /**
1301    * A specialized version of `_.indexOf` which performs strict equality
1302    * comparisons of values, i.e. `===`.
1303    *
1304    * @private
1305    * @param {Array} array The array to inspect.
1306    * @param {*} value The value to search for.
1307    * @param {number} fromIndex The index to search from.
1308    * @returns {number} Returns the index of the matched value, else `-1`.
1309    */
1310   function strictIndexOf(array, value, fromIndex) {
1311     var index = fromIndex - 1,
1312         length = array.length;
1313
1314     while (++index < length) {
1315       if (array[index] === value) {
1316         return index;
1317       }
1318     }
1319     return -1;
1320   }
1321
1322   /**
1323    * A specialized version of `_.lastIndexOf` which performs strict equality
1324    * comparisons of values, i.e. `===`.
1325    *
1326    * @private
1327    * @param {Array} array The array to inspect.
1328    * @param {*} value The value to search for.
1329    * @param {number} fromIndex The index to search from.
1330    * @returns {number} Returns the index of the matched value, else `-1`.
1331    */
1332   function strictLastIndexOf(array, value, fromIndex) {
1333     var index = fromIndex + 1;
1334     while (index--) {
1335       if (array[index] === value) {
1336         return index;
1337       }
1338     }
1339     return index;
1340   }
1341
1342   /**
1343    * Gets the number of symbols in `string`.
1344    *
1345    * @private
1346    * @param {string} string The string to inspect.
1347    * @returns {number} Returns the string size.
1348    */
1349   function stringSize(string) {
1350     return hasUnicode(string)
1351       ? unicodeSize(string)
1352       : asciiSize(string);
1353   }
1354
1355   /**
1356    * Converts `string` to an array.
1357    *
1358    * @private
1359    * @param {string} string The string to convert.
1360    * @returns {Array} Returns the converted array.
1361    */
1362   function stringToArray(string) {
1363     return hasUnicode(string)
1364       ? unicodeToArray(string)
1365       : asciiToArray(string);
1366   }
1367
1368   /**
1369    * Used by `_.unescape` to convert HTML entities to characters.
1370    *
1371    * @private
1372    * @param {string} chr The matched character to unescape.
1373    * @returns {string} Returns the unescaped character.
1374    */
1375   var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
1376
1377   /**
1378    * Gets the size of a Unicode `string`.
1379    *
1380    * @private
1381    * @param {string} string The string inspect.
1382    * @returns {number} Returns the string size.
1383    */
1384   function unicodeSize(string) {
1385     var result = reUnicode.lastIndex = 0;
1386     while (reUnicode.test(string)) {
1387       ++result;
1388     }
1389     return result;
1390   }
1391
1392   /**
1393    * Converts a Unicode `string` to an array.
1394    *
1395    * @private
1396    * @param {string} string The string to convert.
1397    * @returns {Array} Returns the converted array.
1398    */
1399   function unicodeToArray(string) {
1400     return string.match(reUnicode) || [];
1401   }
1402
1403   /**
1404    * Splits a Unicode `string` into an array of its words.
1405    *
1406    * @private
1407    * @param {string} The string to inspect.
1408    * @returns {Array} Returns the words of `string`.
1409    */
1410   function unicodeWords(string) {
1411     return string.match(reUnicodeWord) || [];
1412   }
1413
1414   /*--------------------------------------------------------------------------*/
1415
1416   /**
1417    * Create a new pristine `lodash` function using the `context` object.
1418    *
1419    * @static
1420    * @memberOf _
1421    * @since 1.1.0
1422    * @category Util
1423    * @param {Object} [context=root] The context object.
1424    * @returns {Function} Returns a new `lodash` function.
1425    * @example
1426    *
1427    * _.mixin({ 'foo': _.constant('foo') });
1428    *
1429    * var lodash = _.runInContext();
1430    * lodash.mixin({ 'bar': lodash.constant('bar') });
1431    *
1432    * _.isFunction(_.foo);
1433    * // => true
1434    * _.isFunction(_.bar);
1435    * // => false
1436    *
1437    * lodash.isFunction(lodash.foo);
1438    * // => false
1439    * lodash.isFunction(lodash.bar);
1440    * // => true
1441    *
1442    * // Create a suped-up `defer` in Node.js.
1443    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1444    */
1445   var runInContext = (function runInContext(context) {
1446     context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
1447
1448     /** Built-in constructor references. */
1449     var Array = context.Array,
1450         Date = context.Date,
1451         Error = context.Error,
1452         Function = context.Function,
1453         Math = context.Math,
1454         Object = context.Object,
1455         RegExp = context.RegExp,
1456         String = context.String,
1457         TypeError = context.TypeError;
1458
1459     /** Used for built-in method references. */
1460     var arrayProto = Array.prototype,
1461         funcProto = Function.prototype,
1462         objectProto = Object.prototype;
1463
1464     /** Used to detect overreaching core-js shims. */
1465     var coreJsData = context['__core-js_shared__'];
1466
1467     /** Used to resolve the decompiled source of functions. */
1468     var funcToString = funcProto.toString;
1469
1470     /** Used to check objects for own properties. */
1471     var hasOwnProperty = objectProto.hasOwnProperty;
1472
1473     /** Used to generate unique IDs. */
1474     var idCounter = 0;
1475
1476     /** Used to detect methods masquerading as native. */
1477     var maskSrcKey = (function() {
1478       var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1479       return uid ? ('Symbol(src)_1.' + uid) : '';
1480     }());
1481
1482     /**
1483      * Used to resolve the
1484      * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1485      * of values.
1486      */
1487     var nativeObjectToString = objectProto.toString;
1488
1489     /** Used to infer the `Object` constructor. */
1490     var objectCtorString = funcToString.call(Object);
1491
1492     /** Used to restore the original `_` reference in `_.noConflict`. */
1493     var oldDash = root._;
1494
1495     /** Used to detect if a method is native. */
1496     var reIsNative = RegExp('^' +
1497       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1498       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1499     );
1500
1501     /** Built-in value references. */
1502     var Buffer = moduleExports ? context.Buffer : undefined,
1503         Symbol = context.Symbol,
1504         Uint8Array = context.Uint8Array,
1505         allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
1506         getPrototype = overArg(Object.getPrototypeOf, Object),
1507         objectCreate = Object.create,
1508         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1509         splice = arrayProto.splice,
1510         spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
1511         symIterator = Symbol ? Symbol.iterator : undefined,
1512         symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1513
1514     var defineProperty = (function() {
1515       try {
1516         var func = getNative(Object, 'defineProperty');
1517         func({}, '', {});
1518         return func;
1519       } catch (e) {}
1520     }());
1521
1522     /** Mocked built-ins. */
1523     var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
1524         ctxNow = Date && Date.now !== root.Date.now && Date.now,
1525         ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1526
1527     /* Built-in method references for those with the same name as other `lodash` methods. */
1528     var nativeCeil = Math.ceil,
1529         nativeFloor = Math.floor,
1530         nativeGetSymbols = Object.getOwnPropertySymbols,
1531         nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1532         nativeIsFinite = context.isFinite,
1533         nativeJoin = arrayProto.join,
1534         nativeKeys = overArg(Object.keys, Object),
1535         nativeMax = Math.max,
1536         nativeMin = Math.min,
1537         nativeNow = Date.now,
1538         nativeParseInt = context.parseInt,
1539         nativeRandom = Math.random,
1540         nativeReverse = arrayProto.reverse;
1541
1542     /* Built-in method references that are verified to be native. */
1543     var DataView = getNative(context, 'DataView'),
1544         Map = getNative(context, 'Map'),
1545         Promise = getNative(context, 'Promise'),
1546         Set = getNative(context, 'Set'),
1547         WeakMap = getNative(context, 'WeakMap'),
1548         nativeCreate = getNative(Object, 'create');
1549
1550     /** Used to store function metadata. */
1551     var metaMap = WeakMap && new WeakMap;
1552
1553     /** Used to lookup unminified function names. */
1554     var realNames = {};
1555
1556     /** Used to detect maps, sets, and weakmaps. */
1557     var dataViewCtorString = toSource(DataView),
1558         mapCtorString = toSource(Map),
1559         promiseCtorString = toSource(Promise),
1560         setCtorString = toSource(Set),
1561         weakMapCtorString = toSource(WeakMap);
1562
1563     /** Used to convert symbols to primitives and strings. */
1564     var symbolProto = Symbol ? Symbol.prototype : undefined,
1565         symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1566         symbolToString = symbolProto ? symbolProto.toString : undefined;
1567
1568     /*------------------------------------------------------------------------*/
1569
1570     /**
1571      * Creates a `lodash` object which wraps `value` to enable implicit method
1572      * chain sequences. Methods that operate on and return arrays, collections,
1573      * and functions can be chained together. Methods that retrieve a single value
1574      * or may return a primitive value will automatically end the chain sequence
1575      * and return the unwrapped value. Otherwise, the value must be unwrapped
1576      * with `_#value`.
1577      *
1578      * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1579      * enabled using `_.chain`.
1580      *
1581      * The execution of chained methods is lazy, that is, it's deferred until
1582      * `_#value` is implicitly or explicitly called.
1583      *
1584      * Lazy evaluation allows several methods to support shortcut fusion.
1585      * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1586      * the creation of intermediate arrays and can greatly reduce the number of
1587      * iteratee executions. Sections of a chain sequence qualify for shortcut
1588      * fusion if the section is applied to an array and iteratees accept only
1589      * one argument. The heuristic for whether a section qualifies for shortcut
1590      * fusion is subject to change.
1591      *
1592      * Chaining is supported in custom builds as long as the `_#value` method is
1593      * directly or indirectly included in the build.
1594      *
1595      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1596      *
1597      * The wrapper `Array` methods are:
1598      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1599      *
1600      * The wrapper `String` methods are:
1601      * `replace` and `split`
1602      *
1603      * The wrapper methods that support shortcut fusion are:
1604      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1605      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1606      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1607      *
1608      * The chainable wrapper methods are:
1609      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1610      * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1611      * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1612      * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1613      * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1614      * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1615      * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1616      * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1617      * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1618      * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1619      * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1620      * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1621      * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1622      * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1623      * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1624      * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1625      * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1626      * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1627      * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1628      * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1629      * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1630      * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1631      * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1632      * `zipObject`, `zipObjectDeep`, and `zipWith`
1633      *
1634      * The wrapper methods that are **not** chainable by default are:
1635      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1636      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
1637      * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
1638      * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1639      * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
1640      * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1641      * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1642      * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
1643      * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
1644      * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
1645      * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1646      * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1647      * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1648      * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1649      * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1650      * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1651      * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1652      * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1653      * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1654      * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1655      * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1656      * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1657      * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1658      * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1659      * `upperFirst`, `value`, and `words`
1660      *
1661      * @name _
1662      * @constructor
1663      * @category Seq
1664      * @param {*} value The value to wrap in a `lodash` instance.
1665      * @returns {Object} Returns the new `lodash` wrapper instance.
1666      * @example
1667      *
1668      * function square(n) {
1669      *   return n * n;
1670      * }
1671      *
1672      * var wrapped = _([1, 2, 3]);
1673      *
1674      * // Returns an unwrapped value.
1675      * wrapped.reduce(_.add);
1676      * // => 6
1677      *
1678      * // Returns a wrapped value.
1679      * var squares = wrapped.map(square);
1680      *
1681      * _.isArray(squares);
1682      * // => false
1683      *
1684      * _.isArray(squares.value());
1685      * // => true
1686      */
1687     function lodash(value) {
1688       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1689         if (value instanceof LodashWrapper) {
1690           return value;
1691         }
1692         if (hasOwnProperty.call(value, '__wrapped__')) {
1693           return wrapperClone(value);
1694         }
1695       }
1696       return new LodashWrapper(value);
1697     }
1698
1699     /**
1700      * The base implementation of `_.create` without support for assigning
1701      * properties to the created object.
1702      *
1703      * @private
1704      * @param {Object} proto The object to inherit from.
1705      * @returns {Object} Returns the new object.
1706      */
1707     var baseCreate = (function() {
1708       function object() {}
1709       return function(proto) {
1710         if (!isObject(proto)) {
1711           return {};
1712         }
1713         if (objectCreate) {
1714           return objectCreate(proto);
1715         }
1716         object.prototype = proto;
1717         var result = new object;
1718         object.prototype = undefined;
1719         return result;
1720       };
1721     }());
1722
1723     /**
1724      * The function whose prototype chain sequence wrappers inherit from.
1725      *
1726      * @private
1727      */
1728     function baseLodash() {
1729       // No operation performed.
1730     }
1731
1732     /**
1733      * The base constructor for creating `lodash` wrapper objects.
1734      *
1735      * @private
1736      * @param {*} value The value to wrap.
1737      * @param {boolean} [chainAll] Enable explicit method chain sequences.
1738      */
1739     function LodashWrapper(value, chainAll) {
1740       this.__wrapped__ = value;
1741       this.__actions__ = [];
1742       this.__chain__ = !!chainAll;
1743       this.__index__ = 0;
1744       this.__values__ = undefined;
1745     }
1746
1747     /**
1748      * By default, the template delimiters used by lodash are like those in
1749      * embedded Ruby (ERB) as well as ES2015 template strings. Change the
1750      * following template settings to use alternative delimiters.
1751      *
1752      * @static
1753      * @memberOf _
1754      * @type {Object}
1755      */
1756     lodash.templateSettings = {
1757
1758       /**
1759        * Used to detect `data` property values to be HTML-escaped.
1760        *
1761        * @memberOf _.templateSettings
1762        * @type {RegExp}
1763        */
1764       'escape': reEscape,
1765
1766       /**
1767        * Used to detect code to be evaluated.
1768        *
1769        * @memberOf _.templateSettings
1770        * @type {RegExp}
1771        */
1772       'evaluate': reEvaluate,
1773
1774       /**
1775        * Used to detect `data` property values to inject.
1776        *
1777        * @memberOf _.templateSettings
1778        * @type {RegExp}
1779        */
1780       'interpolate': reInterpolate,
1781
1782       /**
1783        * Used to reference the data object in the template text.
1784        *
1785        * @memberOf _.templateSettings
1786        * @type {string}
1787        */
1788       'variable': '',
1789
1790       /**
1791        * Used to import variables into the compiled template.
1792        *
1793        * @memberOf _.templateSettings
1794        * @type {Object}
1795        */
1796       'imports': {
1797
1798         /**
1799          * A reference to the `lodash` function.
1800          *
1801          * @memberOf _.templateSettings.imports
1802          * @type {Function}
1803          */
1804         '_': lodash
1805       }
1806     };
1807
1808     // Ensure wrappers are instances of `baseLodash`.
1809     lodash.prototype = baseLodash.prototype;
1810     lodash.prototype.constructor = lodash;
1811
1812     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1813     LodashWrapper.prototype.constructor = LodashWrapper;
1814
1815     /*------------------------------------------------------------------------*/
1816
1817     /**
1818      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1819      *
1820      * @private
1821      * @constructor
1822      * @param {*} value The value to wrap.
1823      */
1824     function LazyWrapper(value) {
1825       this.__wrapped__ = value;
1826       this.__actions__ = [];
1827       this.__dir__ = 1;
1828       this.__filtered__ = false;
1829       this.__iteratees__ = [];
1830       this.__takeCount__ = MAX_ARRAY_LENGTH;
1831       this.__views__ = [];
1832     }
1833
1834     /**
1835      * Creates a clone of the lazy wrapper object.
1836      *
1837      * @private
1838      * @name clone
1839      * @memberOf LazyWrapper
1840      * @returns {Object} Returns the cloned `LazyWrapper` object.
1841      */
1842     function lazyClone() {
1843       var result = new LazyWrapper(this.__wrapped__);
1844       result.__actions__ = copyArray(this.__actions__);
1845       result.__dir__ = this.__dir__;
1846       result.__filtered__ = this.__filtered__;
1847       result.__iteratees__ = copyArray(this.__iteratees__);
1848       result.__takeCount__ = this.__takeCount__;
1849       result.__views__ = copyArray(this.__views__);
1850       return result;
1851     }
1852
1853     /**
1854      * Reverses the direction of lazy iteration.
1855      *
1856      * @private
1857      * @name reverse
1858      * @memberOf LazyWrapper
1859      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1860      */
1861     function lazyReverse() {
1862       if (this.__filtered__) {
1863         var result = new LazyWrapper(this);
1864         result.__dir__ = -1;
1865         result.__filtered__ = true;
1866       } else {
1867         result = this.clone();
1868         result.__dir__ *= -1;
1869       }
1870       return result;
1871     }
1872
1873     /**
1874      * Extracts the unwrapped value from its lazy wrapper.
1875      *
1876      * @private
1877      * @name value
1878      * @memberOf LazyWrapper
1879      * @returns {*} Returns the unwrapped value.
1880      */
1881     function lazyValue() {
1882       var array = this.__wrapped__.value(),
1883           dir = this.__dir__,
1884           isArr = isArray(array),
1885           isRight = dir < 0,
1886           arrLength = isArr ? array.length : 0,
1887           view = getView(0, arrLength, this.__views__),
1888           start = view.start,
1889           end = view.end,
1890           length = end - start,
1891           index = isRight ? end : (start - 1),
1892           iteratees = this.__iteratees__,
1893           iterLength = iteratees.length,
1894           resIndex = 0,
1895           takeCount = nativeMin(length, this.__takeCount__);
1896
1897       if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
1898         return baseWrapperValue(array, this.__actions__);
1899       }
1900       var result = [];
1901
1902       outer:
1903       while (length-- && resIndex < takeCount) {
1904         index += dir;
1905
1906         var iterIndex = -1,
1907             value = array[index];
1908
1909         while (++iterIndex < iterLength) {
1910           var data = iteratees[iterIndex],
1911               iteratee = data.iteratee,
1912               type = data.type,
1913               computed = iteratee(value);
1914
1915           if (type == LAZY_MAP_FLAG) {
1916             value = computed;
1917           } else if (!computed) {
1918             if (type == LAZY_FILTER_FLAG) {
1919               continue outer;
1920             } else {
1921               break outer;
1922             }
1923           }
1924         }
1925         result[resIndex++] = value;
1926       }
1927       return result;
1928     }
1929
1930     // Ensure `LazyWrapper` is an instance of `baseLodash`.
1931     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1932     LazyWrapper.prototype.constructor = LazyWrapper;
1933
1934     /*------------------------------------------------------------------------*/
1935
1936     /**
1937      * Creates a hash object.
1938      *
1939      * @private
1940      * @constructor
1941      * @param {Array} [entries] The key-value pairs to cache.
1942      */
1943     function Hash(entries) {
1944       var index = -1,
1945           length = entries == null ? 0 : entries.length;
1946
1947       this.clear();
1948       while (++index < length) {
1949         var entry = entries[index];
1950         this.set(entry[0], entry[1]);
1951       }
1952     }
1953
1954     /**
1955      * Removes all key-value entries from the hash.
1956      *
1957      * @private
1958      * @name clear
1959      * @memberOf Hash
1960      */
1961     function hashClear() {
1962       this.__data__ = nativeCreate ? nativeCreate(null) : {};
1963       this.size = 0;
1964     }
1965
1966     /**
1967      * Removes `key` and its value from the hash.
1968      *
1969      * @private
1970      * @name delete
1971      * @memberOf Hash
1972      * @param {Object} hash The hash to modify.
1973      * @param {string} key The key of the value to remove.
1974      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1975      */
1976     function hashDelete(key) {
1977       var result = this.has(key) && delete this.__data__[key];
1978       this.size -= result ? 1 : 0;
1979       return result;
1980     }
1981
1982     /**
1983      * Gets the hash value for `key`.
1984      *
1985      * @private
1986      * @name get
1987      * @memberOf Hash
1988      * @param {string} key The key of the value to get.
1989      * @returns {*} Returns the entry value.
1990      */
1991     function hashGet(key) {
1992       var data = this.__data__;
1993       if (nativeCreate) {
1994         var result = data[key];
1995         return result === HASH_UNDEFINED ? undefined : result;
1996       }
1997       return hasOwnProperty.call(data, key) ? data[key] : undefined;
1998     }
1999
2000     /**
2001      * Checks if a hash value for `key` exists.
2002      *
2003      * @private
2004      * @name has
2005      * @memberOf Hash
2006      * @param {string} key The key of the entry to check.
2007      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2008      */
2009     function hashHas(key) {
2010       var data = this.__data__;
2011       return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
2012     }
2013
2014     /**
2015      * Sets the hash `key` to `value`.
2016      *
2017      * @private
2018      * @name set
2019      * @memberOf Hash
2020      * @param {string} key The key of the value to set.
2021      * @param {*} value The value to set.
2022      * @returns {Object} Returns the hash instance.
2023      */
2024     function hashSet(key, value) {
2025       var data = this.__data__;
2026       this.size += this.has(key) ? 0 : 1;
2027       data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
2028       return this;
2029     }
2030
2031     // Add methods to `Hash`.
2032     Hash.prototype.clear = hashClear;
2033     Hash.prototype['delete'] = hashDelete;
2034     Hash.prototype.get = hashGet;
2035     Hash.prototype.has = hashHas;
2036     Hash.prototype.set = hashSet;
2037
2038     /*------------------------------------------------------------------------*/
2039
2040     /**
2041      * Creates an list cache object.
2042      *
2043      * @private
2044      * @constructor
2045      * @param {Array} [entries] The key-value pairs to cache.
2046      */
2047     function ListCache(entries) {
2048       var index = -1,
2049           length = entries == null ? 0 : entries.length;
2050
2051       this.clear();
2052       while (++index < length) {
2053         var entry = entries[index];
2054         this.set(entry[0], entry[1]);
2055       }
2056     }
2057
2058     /**
2059      * Removes all key-value entries from the list cache.
2060      *
2061      * @private
2062      * @name clear
2063      * @memberOf ListCache
2064      */
2065     function listCacheClear() {
2066       this.__data__ = [];
2067       this.size = 0;
2068     }
2069
2070     /**
2071      * Removes `key` and its value from the list cache.
2072      *
2073      * @private
2074      * @name delete
2075      * @memberOf ListCache
2076      * @param {string} key The key of the value to remove.
2077      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2078      */
2079     function listCacheDelete(key) {
2080       var data = this.__data__,
2081           index = assocIndexOf(data, key);
2082
2083       if (index < 0) {
2084         return false;
2085       }
2086       var lastIndex = data.length - 1;
2087       if (index == lastIndex) {
2088         data.pop();
2089       } else {
2090         splice.call(data, index, 1);
2091       }
2092       --this.size;
2093       return true;
2094     }
2095
2096     /**
2097      * Gets the list cache value for `key`.
2098      *
2099      * @private
2100      * @name get
2101      * @memberOf ListCache
2102      * @param {string} key The key of the value to get.
2103      * @returns {*} Returns the entry value.
2104      */
2105     function listCacheGet(key) {
2106       var data = this.__data__,
2107           index = assocIndexOf(data, key);
2108
2109       return index < 0 ? undefined : data[index][1];
2110     }
2111
2112     /**
2113      * Checks if a list cache value for `key` exists.
2114      *
2115      * @private
2116      * @name has
2117      * @memberOf ListCache
2118      * @param {string} key The key of the entry to check.
2119      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2120      */
2121     function listCacheHas(key) {
2122       return assocIndexOf(this.__data__, key) > -1;
2123     }
2124
2125     /**
2126      * Sets the list cache `key` to `value`.
2127      *
2128      * @private
2129      * @name set
2130      * @memberOf ListCache
2131      * @param {string} key The key of the value to set.
2132      * @param {*} value The value to set.
2133      * @returns {Object} Returns the list cache instance.
2134      */
2135     function listCacheSet(key, value) {
2136       var data = this.__data__,
2137           index = assocIndexOf(data, key);
2138
2139       if (index < 0) {
2140         ++this.size;
2141         data.push([key, value]);
2142       } else {
2143         data[index][1] = value;
2144       }
2145       return this;
2146     }
2147
2148     // Add methods to `ListCache`.
2149     ListCache.prototype.clear = listCacheClear;
2150     ListCache.prototype['delete'] = listCacheDelete;
2151     ListCache.prototype.get = listCacheGet;
2152     ListCache.prototype.has = listCacheHas;
2153     ListCache.prototype.set = listCacheSet;
2154
2155     /*------------------------------------------------------------------------*/
2156
2157     /**
2158      * Creates a map cache object to store key-value pairs.
2159      *
2160      * @private
2161      * @constructor
2162      * @param {Array} [entries] The key-value pairs to cache.
2163      */
2164     function MapCache(entries) {
2165       var index = -1,
2166           length = entries == null ? 0 : entries.length;
2167
2168       this.clear();
2169       while (++index < length) {
2170         var entry = entries[index];
2171         this.set(entry[0], entry[1]);
2172       }
2173     }
2174
2175     /**
2176      * Removes all key-value entries from the map.
2177      *
2178      * @private
2179      * @name clear
2180      * @memberOf MapCache
2181      */
2182     function mapCacheClear() {
2183       this.size = 0;
2184       this.__data__ = {
2185         'hash': new Hash,
2186         'map': new (Map || ListCache),
2187         'string': new Hash
2188       };
2189     }
2190
2191     /**
2192      * Removes `key` and its value from the map.
2193      *
2194      * @private
2195      * @name delete
2196      * @memberOf MapCache
2197      * @param {string} key The key of the value to remove.
2198      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2199      */
2200     function mapCacheDelete(key) {
2201       var result = getMapData(this, key)['delete'](key);
2202       this.size -= result ? 1 : 0;
2203       return result;
2204     }
2205
2206     /**
2207      * Gets the map value for `key`.
2208      *
2209      * @private
2210      * @name get
2211      * @memberOf MapCache
2212      * @param {string} key The key of the value to get.
2213      * @returns {*} Returns the entry value.
2214      */
2215     function mapCacheGet(key) {
2216       return getMapData(this, key).get(key);
2217     }
2218
2219     /**
2220      * Checks if a map value for `key` exists.
2221      *
2222      * @private
2223      * @name has
2224      * @memberOf MapCache
2225      * @param {string} key The key of the entry to check.
2226      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2227      */
2228     function mapCacheHas(key) {
2229       return getMapData(this, key).has(key);
2230     }
2231
2232     /**
2233      * Sets the map `key` to `value`.
2234      *
2235      * @private
2236      * @name set
2237      * @memberOf MapCache
2238      * @param {string} key The key of the value to set.
2239      * @param {*} value The value to set.
2240      * @returns {Object} Returns the map cache instance.
2241      */
2242     function mapCacheSet(key, value) {
2243       var data = getMapData(this, key),
2244           size = data.size;
2245
2246       data.set(key, value);
2247       this.size += data.size == size ? 0 : 1;
2248       return this;
2249     }
2250
2251     // Add methods to `MapCache`.
2252     MapCache.prototype.clear = mapCacheClear;
2253     MapCache.prototype['delete'] = mapCacheDelete;
2254     MapCache.prototype.get = mapCacheGet;
2255     MapCache.prototype.has = mapCacheHas;
2256     MapCache.prototype.set = mapCacheSet;
2257
2258     /*------------------------------------------------------------------------*/
2259
2260     /**
2261      *
2262      * Creates an array cache object to store unique values.
2263      *
2264      * @private
2265      * @constructor
2266      * @param {Array} [values] The values to cache.
2267      */
2268     function SetCache(values) {
2269       var index = -1,
2270           length = values == null ? 0 : values.length;
2271
2272       this.__data__ = new MapCache;
2273       while (++index < length) {
2274         this.add(values[index]);
2275       }
2276     }
2277
2278     /**
2279      * Adds `value` to the array cache.
2280      *
2281      * @private
2282      * @name add
2283      * @memberOf SetCache
2284      * @alias push
2285      * @param {*} value The value to cache.
2286      * @returns {Object} Returns the cache instance.
2287      */
2288     function setCacheAdd(value) {
2289       this.__data__.set(value, HASH_UNDEFINED);
2290       return this;
2291     }
2292
2293     /**
2294      * Checks if `value` is in the array cache.
2295      *
2296      * @private
2297      * @name has
2298      * @memberOf SetCache
2299      * @param {*} value The value to search for.
2300      * @returns {number} Returns `true` if `value` is found, else `false`.
2301      */
2302     function setCacheHas(value) {
2303       return this.__data__.has(value);
2304     }
2305
2306     // Add methods to `SetCache`.
2307     SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2308     SetCache.prototype.has = setCacheHas;
2309
2310     /*------------------------------------------------------------------------*/
2311
2312     /**
2313      * Creates a stack cache object to store key-value pairs.
2314      *
2315      * @private
2316      * @constructor
2317      * @param {Array} [entries] The key-value pairs to cache.
2318      */
2319     function Stack(entries) {
2320       var data = this.__data__ = new ListCache(entries);
2321       this.size = data.size;
2322     }
2323
2324     /**
2325      * Removes all key-value entries from the stack.
2326      *
2327      * @private
2328      * @name clear
2329      * @memberOf Stack
2330      */
2331     function stackClear() {
2332       this.__data__ = new ListCache;
2333       this.size = 0;
2334     }
2335
2336     /**
2337      * Removes `key` and its value from the stack.
2338      *
2339      * @private
2340      * @name delete
2341      * @memberOf Stack
2342      * @param {string} key The key of the value to remove.
2343      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2344      */
2345     function stackDelete(key) {
2346       var data = this.__data__,
2347           result = data['delete'](key);
2348
2349       this.size = data.size;
2350       return result;
2351     }
2352
2353     /**
2354      * Gets the stack value for `key`.
2355      *
2356      * @private
2357      * @name get
2358      * @memberOf Stack
2359      * @param {string} key The key of the value to get.
2360      * @returns {*} Returns the entry value.
2361      */
2362     function stackGet(key) {
2363       return this.__data__.get(key);
2364     }
2365
2366     /**
2367      * Checks if a stack value for `key` exists.
2368      *
2369      * @private
2370      * @name has
2371      * @memberOf Stack
2372      * @param {string} key The key of the entry to check.
2373      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2374      */
2375     function stackHas(key) {
2376       return this.__data__.has(key);
2377     }
2378
2379     /**
2380      * Sets the stack `key` to `value`.
2381      *
2382      * @private
2383      * @name set
2384      * @memberOf Stack
2385      * @param {string} key The key of the value to set.
2386      * @param {*} value The value to set.
2387      * @returns {Object} Returns the stack cache instance.
2388      */
2389     function stackSet(key, value) {
2390       var data = this.__data__;
2391       if (data instanceof ListCache) {
2392         var pairs = data.__data__;
2393         if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2394           pairs.push([key, value]);
2395           this.size = ++data.size;
2396           return this;
2397         }
2398         data = this.__data__ = new MapCache(pairs);
2399       }
2400       data.set(key, value);
2401       this.size = data.size;
2402       return this;
2403     }
2404
2405     // Add methods to `Stack`.
2406     Stack.prototype.clear = stackClear;
2407     Stack.prototype['delete'] = stackDelete;
2408     Stack.prototype.get = stackGet;
2409     Stack.prototype.has = stackHas;
2410     Stack.prototype.set = stackSet;
2411
2412     /*------------------------------------------------------------------------*/
2413
2414     /**
2415      * Creates an array of the enumerable property names of the array-like `value`.
2416      *
2417      * @private
2418      * @param {*} value The value to query.
2419      * @param {boolean} inherited Specify returning inherited property names.
2420      * @returns {Array} Returns the array of property names.
2421      */
2422     function arrayLikeKeys(value, inherited) {
2423       var isArr = isArray(value),
2424           isArg = !isArr && isArguments(value),
2425           isBuff = !isArr && !isArg && isBuffer(value),
2426           isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2427           skipIndexes = isArr || isArg || isBuff || isType,
2428           result = skipIndexes ? baseTimes(value.length, String) : [],
2429           length = result.length;
2430
2431       for (var key in value) {
2432         if ((inherited || hasOwnProperty.call(value, key)) &&
2433             !(skipIndexes && (
2434                // Safari 9 has enumerable `arguments.length` in strict mode.
2435                key == 'length' ||
2436                // Node.js 0.10 has enumerable non-index properties on buffers.
2437                (isBuff && (key == 'offset' || key == 'parent')) ||
2438                // PhantomJS 2 has enumerable non-index properties on typed arrays.
2439                (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2440                // Skip index properties.
2441                isIndex(key, length)
2442             ))) {
2443           result.push(key);
2444         }
2445       }
2446       return result;
2447     }
2448
2449     /**
2450      * A specialized version of `_.sample` for arrays.
2451      *
2452      * @private
2453      * @param {Array} array The array to sample.
2454      * @returns {*} Returns the random element.
2455      */
2456     function arraySample(array) {
2457       var length = array.length;
2458       return length ? array[baseRandom(0, length - 1)] : undefined;
2459     }
2460
2461     /**
2462      * A specialized version of `_.sampleSize` for arrays.
2463      *
2464      * @private
2465      * @param {Array} array The array to sample.
2466      * @param {number} n The number of elements to sample.
2467      * @returns {Array} Returns the random elements.
2468      */
2469     function arraySampleSize(array, n) {
2470       return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2471     }
2472
2473     /**
2474      * A specialized version of `_.shuffle` for arrays.
2475      *
2476      * @private
2477      * @param {Array} array The array to shuffle.
2478      * @returns {Array} Returns the new shuffled array.
2479      */
2480     function arrayShuffle(array) {
2481       return shuffleSelf(copyArray(array));
2482     }
2483
2484     /**
2485      * This function is like `assignValue` except that it doesn't assign
2486      * `undefined` values.
2487      *
2488      * @private
2489      * @param {Object} object The object to modify.
2490      * @param {string} key The key of the property to assign.
2491      * @param {*} value The value to assign.
2492      */
2493     function assignMergeValue(object, key, value) {
2494       if ((value !== undefined && !eq(object[key], value)) ||
2495           (value === undefined && !(key in object))) {
2496         baseAssignValue(object, key, value);
2497       }
2498     }
2499
2500     /**
2501      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2502      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2503      * for equality comparisons.
2504      *
2505      * @private
2506      * @param {Object} object The object to modify.
2507      * @param {string} key The key of the property to assign.
2508      * @param {*} value The value to assign.
2509      */
2510     function assignValue(object, key, value) {
2511       var objValue = object[key];
2512       if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2513           (value === undefined && !(key in object))) {
2514         baseAssignValue(object, key, value);
2515       }
2516     }
2517
2518     /**
2519      * Gets the index at which the `key` is found in `array` of key-value pairs.
2520      *
2521      * @private
2522      * @param {Array} array The array to inspect.
2523      * @param {*} key The key to search for.
2524      * @returns {number} Returns the index of the matched value, else `-1`.
2525      */
2526     function assocIndexOf(array, key) {
2527       var length = array.length;
2528       while (length--) {
2529         if (eq(array[length][0], key)) {
2530           return length;
2531         }
2532       }
2533       return -1;
2534     }
2535
2536     /**
2537      * Aggregates elements of `collection` on `accumulator` with keys transformed
2538      * by `iteratee` and values set by `setter`.
2539      *
2540      * @private
2541      * @param {Array|Object} collection The collection to iterate over.
2542      * @param {Function} setter The function to set `accumulator` values.
2543      * @param {Function} iteratee The iteratee to transform keys.
2544      * @param {Object} accumulator The initial aggregated object.
2545      * @returns {Function} Returns `accumulator`.
2546      */
2547     function baseAggregator(collection, setter, iteratee, accumulator) {
2548       baseEach(collection, function(value, key, collection) {
2549         setter(accumulator, value, iteratee(value), collection);
2550       });
2551       return accumulator;
2552     }
2553
2554     /**
2555      * The base implementation of `_.assign` without support for multiple sources
2556      * or `customizer` functions.
2557      *
2558      * @private
2559      * @param {Object} object The destination object.
2560      * @param {Object} source The source object.
2561      * @returns {Object} Returns `object`.
2562      */
2563     function baseAssign(object, source) {
2564       return object && copyObject(source, keys(source), object);
2565     }
2566
2567     /**
2568      * The base implementation of `_.assignIn` without support for multiple sources
2569      * or `customizer` functions.
2570      *
2571      * @private
2572      * @param {Object} object The destination object.
2573      * @param {Object} source The source object.
2574      * @returns {Object} Returns `object`.
2575      */
2576     function baseAssignIn(object, source) {
2577       return object && copyObject(source, keysIn(source), object);
2578     }
2579
2580     /**
2581      * The base implementation of `assignValue` and `assignMergeValue` without
2582      * value checks.
2583      *
2584      * @private
2585      * @param {Object} object The object to modify.
2586      * @param {string} key The key of the property to assign.
2587      * @param {*} value The value to assign.
2588      */
2589     function baseAssignValue(object, key, value) {
2590       if (key == '__proto__' && defineProperty) {
2591         defineProperty(object, key, {
2592           'configurable': true,
2593           'enumerable': true,
2594           'value': value,
2595           'writable': true
2596         });
2597       } else {
2598         object[key] = value;
2599       }
2600     }
2601
2602     /**
2603      * The base implementation of `_.at` without support for individual paths.
2604      *
2605      * @private
2606      * @param {Object} object The object to iterate over.
2607      * @param {string[]} paths The property paths to pick.
2608      * @returns {Array} Returns the picked elements.
2609      */
2610     function baseAt(object, paths) {
2611       var index = -1,
2612           length = paths.length,
2613           result = Array(length),
2614           skip = object == null;
2615
2616       while (++index < length) {
2617         result[index] = skip ? undefined : get(object, paths[index]);
2618       }
2619       return result;
2620     }
2621
2622     /**
2623      * The base implementation of `_.clamp` which doesn't coerce arguments.
2624      *
2625      * @private
2626      * @param {number} number The number to clamp.
2627      * @param {number} [lower] The lower bound.
2628      * @param {number} upper The upper bound.
2629      * @returns {number} Returns the clamped number.
2630      */
2631     function baseClamp(number, lower, upper) {
2632       if (number === number) {
2633         if (upper !== undefined) {
2634           number = number <= upper ? number : upper;
2635         }
2636         if (lower !== undefined) {
2637           number = number >= lower ? number : lower;
2638         }
2639       }
2640       return number;
2641     }
2642
2643     /**
2644      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2645      * traversed objects.
2646      *
2647      * @private
2648      * @param {*} value The value to clone.
2649      * @param {boolean} bitmask The bitmask flags.
2650      *  1 - Deep clone
2651      *  2 - Flatten inherited properties
2652      *  4 - Clone symbols
2653      * @param {Function} [customizer] The function to customize cloning.
2654      * @param {string} [key] The key of `value`.
2655      * @param {Object} [object] The parent object of `value`.
2656      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2657      * @returns {*} Returns the cloned value.
2658      */
2659     function baseClone(value, bitmask, customizer, key, object, stack) {
2660       var result,
2661           isDeep = bitmask & CLONE_DEEP_FLAG,
2662           isFlat = bitmask & CLONE_FLAT_FLAG,
2663           isFull = bitmask & CLONE_SYMBOLS_FLAG;
2664
2665       if (customizer) {
2666         result = object ? customizer(value, key, object, stack) : customizer(value);
2667       }
2668       if (result !== undefined) {
2669         return result;
2670       }
2671       if (!isObject(value)) {
2672         return value;
2673       }
2674       var isArr = isArray(value);
2675       if (isArr) {
2676         result = initCloneArray(value);
2677         if (!isDeep) {
2678           return copyArray(value, result);
2679         }
2680       } else {
2681         var tag = getTag(value),
2682             isFunc = tag == funcTag || tag == genTag;
2683
2684         if (isBuffer(value)) {
2685           return cloneBuffer(value, isDeep);
2686         }
2687         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2688           result = (isFlat || isFunc) ? {} : initCloneObject(value);
2689           if (!isDeep) {
2690             return isFlat
2691               ? copySymbolsIn(value, baseAssignIn(result, value))
2692               : copySymbols(value, baseAssign(result, value));
2693           }
2694         } else {
2695           if (!cloneableTags[tag]) {
2696             return object ? value : {};
2697           }
2698           result = initCloneByTag(value, tag, baseClone, isDeep);
2699         }
2700       }
2701       // Check for circular references and return its corresponding clone.
2702       stack || (stack = new Stack);
2703       var stacked = stack.get(value);
2704       if (stacked) {
2705         return stacked;
2706       }
2707       stack.set(value, result);
2708
2709       var keysFunc = isFull
2710         ? (isFlat ? getAllKeysIn : getAllKeys)
2711         : (isFlat ? keysIn : keys);
2712
2713       var props = isArr ? undefined : keysFunc(value);
2714       arrayEach(props || value, function(subValue, key) {
2715         if (props) {
2716           key = subValue;
2717           subValue = value[key];
2718         }
2719         // Recursively populate clone (susceptible to call stack limits).
2720         assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2721       });
2722       return result;
2723     }
2724
2725     /**
2726      * The base implementation of `_.conforms` which doesn't clone `source`.
2727      *
2728      * @private
2729      * @param {Object} source The object of property predicates to conform to.
2730      * @returns {Function} Returns the new spec function.
2731      */
2732     function baseConforms(source) {
2733       var props = keys(source);
2734       return function(object) {
2735         return baseConformsTo(object, source, props);
2736       };
2737     }
2738
2739     /**
2740      * The base implementation of `_.conformsTo` which accepts `props` to check.
2741      *
2742      * @private
2743      * @param {Object} object The object to inspect.
2744      * @param {Object} source The object of property predicates to conform to.
2745      * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2746      */
2747     function baseConformsTo(object, source, props) {
2748       var length = props.length;
2749       if (object == null) {
2750         return !length;
2751       }
2752       object = Object(object);
2753       while (length--) {
2754         var key = props[length],
2755             predicate = source[key],
2756             value = object[key];
2757
2758         if ((value === undefined && !(key in object)) || !predicate(value)) {
2759           return false;
2760         }
2761       }
2762       return true;
2763     }
2764
2765     /**
2766      * The base implementation of `_.delay` and `_.defer` which accepts `args`
2767      * to provide to `func`.
2768      *
2769      * @private
2770      * @param {Function} func The function to delay.
2771      * @param {number} wait The number of milliseconds to delay invocation.
2772      * @param {Array} args The arguments to provide to `func`.
2773      * @returns {number|Object} Returns the timer id or timeout object.
2774      */
2775     function baseDelay(func, wait, args) {
2776       if (typeof func != 'function') {
2777         throw new TypeError(FUNC_ERROR_TEXT);
2778       }
2779       return setTimeout(function() { func.apply(undefined, args); }, wait);
2780     }
2781
2782     /**
2783      * The base implementation of methods like `_.difference` without support
2784      * for excluding multiple arrays or iteratee shorthands.
2785      *
2786      * @private
2787      * @param {Array} array The array to inspect.
2788      * @param {Array} values The values to exclude.
2789      * @param {Function} [iteratee] The iteratee invoked per element.
2790      * @param {Function} [comparator] The comparator invoked per element.
2791      * @returns {Array} Returns the new array of filtered values.
2792      */
2793     function baseDifference(array, values, iteratee, comparator) {
2794       var index = -1,
2795           includes = arrayIncludes,
2796           isCommon = true,
2797           length = array.length,
2798           result = [],
2799           valuesLength = values.length;
2800
2801       if (!length) {
2802         return result;
2803       }
2804       if (iteratee) {
2805         values = arrayMap(values, baseUnary(iteratee));
2806       }
2807       if (comparator) {
2808         includes = arrayIncludesWith;
2809         isCommon = false;
2810       }
2811       else if (values.length >= LARGE_ARRAY_SIZE) {
2812         includes = cacheHas;
2813         isCommon = false;
2814         values = new SetCache(values);
2815       }
2816       outer:
2817       while (++index < length) {
2818         var value = array[index],
2819             computed = iteratee == null ? value : iteratee(value);
2820
2821         value = (comparator || value !== 0) ? value : 0;
2822         if (isCommon && computed === computed) {
2823           var valuesIndex = valuesLength;
2824           while (valuesIndex--) {
2825             if (values[valuesIndex] === computed) {
2826               continue outer;
2827             }
2828           }
2829           result.push(value);
2830         }
2831         else if (!includes(values, computed, comparator)) {
2832           result.push(value);
2833         }
2834       }
2835       return result;
2836     }
2837
2838     /**
2839      * The base implementation of `_.forEach` without support for iteratee shorthands.
2840      *
2841      * @private
2842      * @param {Array|Object} collection The collection to iterate over.
2843      * @param {Function} iteratee The function invoked per iteration.
2844      * @returns {Array|Object} Returns `collection`.
2845      */
2846     var baseEach = createBaseEach(baseForOwn);
2847
2848     /**
2849      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2850      *
2851      * @private
2852      * @param {Array|Object} collection The collection to iterate over.
2853      * @param {Function} iteratee The function invoked per iteration.
2854      * @returns {Array|Object} Returns `collection`.
2855      */
2856     var baseEachRight = createBaseEach(baseForOwnRight, true);
2857
2858     /**
2859      * The base implementation of `_.every` without support for iteratee shorthands.
2860      *
2861      * @private
2862      * @param {Array|Object} collection The collection to iterate over.
2863      * @param {Function} predicate The function invoked per iteration.
2864      * @returns {boolean} Returns `true` if all elements pass the predicate check,
2865      *  else `false`
2866      */
2867     function baseEvery(collection, predicate) {
2868       var result = true;
2869       baseEach(collection, function(value, index, collection) {
2870         result = !!predicate(value, index, collection);
2871         return result;
2872       });
2873       return result;
2874     }
2875
2876     /**
2877      * The base implementation of methods like `_.max` and `_.min` which accepts a
2878      * `comparator` to determine the extremum value.
2879      *
2880      * @private
2881      * @param {Array} array The array to iterate over.
2882      * @param {Function} iteratee The iteratee invoked per iteration.
2883      * @param {Function} comparator The comparator used to compare values.
2884      * @returns {*} Returns the extremum value.
2885      */
2886     function baseExtremum(array, iteratee, comparator) {
2887       var index = -1,
2888           length = array.length;
2889
2890       while (++index < length) {
2891         var value = array[index],
2892             current = iteratee(value);
2893
2894         if (current != null && (computed === undefined
2895               ? (current === current && !isSymbol(current))
2896               : comparator(current, computed)
2897             )) {
2898           var computed = current,
2899               result = value;
2900         }
2901       }
2902       return result;
2903     }
2904
2905     /**
2906      * The base implementation of `_.fill` without an iteratee call guard.
2907      *
2908      * @private
2909      * @param {Array} array The array to fill.
2910      * @param {*} value The value to fill `array` with.
2911      * @param {number} [start=0] The start position.
2912      * @param {number} [end=array.length] The end position.
2913      * @returns {Array} Returns `array`.
2914      */
2915     function baseFill(array, value, start, end) {
2916       var length = array.length;
2917
2918       start = toInteger(start);
2919       if (start < 0) {
2920         start = -start > length ? 0 : (length + start);
2921       }
2922       end = (end === undefined || end > length) ? length : toInteger(end);
2923       if (end < 0) {
2924         end += length;
2925       }
2926       end = start > end ? 0 : toLength(end);
2927       while (start < end) {
2928         array[start++] = value;
2929       }
2930       return array;
2931     }
2932
2933     /**
2934      * The base implementation of `_.filter` without support for iteratee shorthands.
2935      *
2936      * @private
2937      * @param {Array|Object} collection The collection to iterate over.
2938      * @param {Function} predicate The function invoked per iteration.
2939      * @returns {Array} Returns the new filtered array.
2940      */
2941     function baseFilter(collection, predicate) {
2942       var result = [];
2943       baseEach(collection, function(value, index, collection) {
2944         if (predicate(value, index, collection)) {
2945           result.push(value);
2946         }
2947       });
2948       return result;
2949     }
2950
2951     /**
2952      * The base implementation of `_.flatten` with support for restricting flattening.
2953      *
2954      * @private
2955      * @param {Array} array The array to flatten.
2956      * @param {number} depth The maximum recursion depth.
2957      * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2958      * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2959      * @param {Array} [result=[]] The initial result value.
2960      * @returns {Array} Returns the new flattened array.
2961      */
2962     function baseFlatten(array, depth, predicate, isStrict, result) {
2963       var index = -1,
2964           length = array.length;
2965
2966       predicate || (predicate = isFlattenable);
2967       result || (result = []);
2968
2969       while (++index < length) {
2970         var value = array[index];
2971         if (depth > 0 && predicate(value)) {
2972           if (depth > 1) {
2973             // Recursively flatten arrays (susceptible to call stack limits).
2974             baseFlatten(value, depth - 1, predicate, isStrict, result);
2975           } else {
2976             arrayPush(result, value);
2977           }
2978         } else if (!isStrict) {
2979           result[result.length] = value;
2980         }
2981       }
2982       return result;
2983     }
2984
2985     /**
2986      * The base implementation of `baseForOwn` which iterates over `object`
2987      * properties returned by `keysFunc` and invokes `iteratee` for each property.
2988      * Iteratee functions may exit iteration early by explicitly returning `false`.
2989      *
2990      * @private
2991      * @param {Object} object The object to iterate over.
2992      * @param {Function} iteratee The function invoked per iteration.
2993      * @param {Function} keysFunc The function to get the keys of `object`.
2994      * @returns {Object} Returns `object`.
2995      */
2996     var baseFor = createBaseFor();
2997
2998     /**
2999      * This function is like `baseFor` except that it iterates over properties
3000      * in the opposite order.
3001      *
3002      * @private
3003      * @param {Object} object The object to iterate over.
3004      * @param {Function} iteratee The function invoked per iteration.
3005      * @param {Function} keysFunc The function to get the keys of `object`.
3006      * @returns {Object} Returns `object`.
3007      */
3008     var baseForRight = createBaseFor(true);
3009
3010     /**
3011      * The base implementation of `_.forOwn` without support for iteratee shorthands.
3012      *
3013      * @private
3014      * @param {Object} object The object to iterate over.
3015      * @param {Function} iteratee The function invoked per iteration.
3016      * @returns {Object} Returns `object`.
3017      */
3018     function baseForOwn(object, iteratee) {
3019       return object && baseFor(object, iteratee, keys);
3020     }
3021
3022     /**
3023      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
3024      *
3025      * @private
3026      * @param {Object} object The object to iterate over.
3027      * @param {Function} iteratee The function invoked per iteration.
3028      * @returns {Object} Returns `object`.
3029      */
3030     function baseForOwnRight(object, iteratee) {
3031       return object && baseForRight(object, iteratee, keys);
3032     }
3033
3034     /**
3035      * The base implementation of `_.functions` which creates an array of
3036      * `object` function property names filtered from `props`.
3037      *
3038      * @private
3039      * @param {Object} object The object to inspect.
3040      * @param {Array} props The property names to filter.
3041      * @returns {Array} Returns the function names.
3042      */
3043     function baseFunctions(object, props) {
3044       return arrayFilter(props, function(key) {
3045         return isFunction(object[key]);
3046       });
3047     }
3048
3049     /**
3050      * The base implementation of `_.get` without support for default values.
3051      *
3052      * @private
3053      * @param {Object} object The object to query.
3054      * @param {Array|string} path The path of the property to get.
3055      * @returns {*} Returns the resolved value.
3056      */
3057     function baseGet(object, path) {
3058       path = castPath(path, object);
3059
3060       var index = 0,
3061           length = path.length;
3062
3063       while (object != null && index < length) {
3064         object = object[toKey(path[index++])];
3065       }
3066       return (index && index == length) ? object : undefined;
3067     }
3068
3069     /**
3070      * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3071      * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3072      * symbols of `object`.
3073      *
3074      * @private
3075      * @param {Object} object The object to query.
3076      * @param {Function} keysFunc The function to get the keys of `object`.
3077      * @param {Function} symbolsFunc The function to get the symbols of `object`.
3078      * @returns {Array} Returns the array of property names and symbols.
3079      */
3080     function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3081       var result = keysFunc(object);
3082       return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3083     }
3084
3085     /**
3086      * The base implementation of `getTag` without fallbacks for buggy environments.
3087      *
3088      * @private
3089      * @param {*} value The value to query.
3090      * @returns {string} Returns the `toStringTag`.
3091      */
3092     function baseGetTag(value) {
3093       if (value == null) {
3094         return value === undefined ? undefinedTag : nullTag;
3095       }
3096       return (symToStringTag && symToStringTag in Object(value))
3097         ? getRawTag(value)
3098         : objectToString(value);
3099     }
3100
3101     /**
3102      * The base implementation of `_.gt` which doesn't coerce arguments.
3103      *
3104      * @private
3105      * @param {*} value The value to compare.
3106      * @param {*} other The other value to compare.
3107      * @returns {boolean} Returns `true` if `value` is greater than `other`,
3108      *  else `false`.
3109      */
3110     function baseGt(value, other) {
3111       return value > other;
3112     }
3113
3114     /**
3115      * The base implementation of `_.has` without support for deep paths.
3116      *
3117      * @private
3118      * @param {Object} [object] The object to query.
3119      * @param {Array|string} key The key to check.
3120      * @returns {boolean} Returns `true` if `key` exists, else `false`.
3121      */
3122     function baseHas(object, key) {
3123       return object != null && hasOwnProperty.call(object, key);
3124     }
3125
3126     /**
3127      * The base implementation of `_.hasIn` without support for deep paths.
3128      *
3129      * @private
3130      * @param {Object} [object] The object to query.
3131      * @param {Array|string} key The key to check.
3132      * @returns {boolean} Returns `true` if `key` exists, else `false`.
3133      */
3134     function baseHasIn(object, key) {
3135       return object != null && key in Object(object);
3136     }
3137
3138     /**
3139      * The base implementation of `_.inRange` which doesn't coerce arguments.
3140      *
3141      * @private
3142      * @param {number} number The number to check.
3143      * @param {number} start The start of the range.
3144      * @param {number} end The end of the range.
3145      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3146      */
3147     function baseInRange(number, start, end) {
3148       return number >= nativeMin(start, end) && number < nativeMax(start, end);
3149     }
3150
3151     /**
3152      * The base implementation of methods like `_.intersection`, without support
3153      * for iteratee shorthands, that accepts an array of arrays to inspect.
3154      *
3155      * @private
3156      * @param {Array} arrays The arrays to inspect.
3157      * @param {Function} [iteratee] The iteratee invoked per element.
3158      * @param {Function} [comparator] The comparator invoked per element.
3159      * @returns {Array} Returns the new array of shared values.
3160      */
3161     function baseIntersection(arrays, iteratee, comparator) {
3162       var includes = comparator ? arrayIncludesWith : arrayIncludes,
3163           length = arrays[0].length,
3164           othLength = arrays.length,
3165           othIndex = othLength,
3166           caches = Array(othLength),
3167           maxLength = Infinity,
3168           result = [];
3169
3170       while (othIndex--) {
3171         var array = arrays[othIndex];
3172         if (othIndex && iteratee) {
3173           array = arrayMap(array, baseUnary(iteratee));
3174         }
3175         maxLength = nativeMin(array.length, maxLength);
3176         caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3177           ? new SetCache(othIndex && array)
3178           : undefined;
3179       }
3180       array = arrays[0];
3181
3182       var index = -1,
3183           seen = caches[0];
3184
3185       outer:
3186       while (++index < length && result.length < maxLength) {
3187         var value = array[index],
3188             computed = iteratee ? iteratee(value) : value;
3189
3190         value = (comparator || value !== 0) ? value : 0;
3191         if (!(seen
3192               ? cacheHas(seen, computed)
3193               : includes(result, computed, comparator)
3194             )) {
3195           othIndex = othLength;
3196           while (--othIndex) {
3197             var cache = caches[othIndex];
3198             if (!(cache
3199                   ? cacheHas(cache, computed)
3200                   : includes(arrays[othIndex], computed, comparator))
3201                 ) {
3202               continue outer;
3203             }
3204           }
3205           if (seen) {
3206             seen.push(computed);
3207           }
3208           result.push(value);
3209         }
3210       }
3211       return result;
3212     }
3213
3214     /**
3215      * The base implementation of `_.invert` and `_.invertBy` which inverts
3216      * `object` with values transformed by `iteratee` and set by `setter`.
3217      *
3218      * @private
3219      * @param {Object} object The object to iterate over.
3220      * @param {Function} setter The function to set `accumulator` values.
3221      * @param {Function} iteratee The iteratee to transform values.
3222      * @param {Object} accumulator The initial inverted object.
3223      * @returns {Function} Returns `accumulator`.
3224      */
3225     function baseInverter(object, setter, iteratee, accumulator) {
3226       baseForOwn(object, function(value, key, object) {
3227         setter(accumulator, iteratee(value), key, object);
3228       });
3229       return accumulator;
3230     }
3231
3232     /**
3233      * The base implementation of `_.invoke` without support for individual
3234      * method arguments.
3235      *
3236      * @private
3237      * @param {Object} object The object to query.
3238      * @param {Array|string} path The path of the method to invoke.
3239      * @param {Array} args The arguments to invoke the method with.
3240      * @returns {*} Returns the result of the invoked method.
3241      */
3242     function baseInvoke(object, path, args) {
3243       path = castPath(path, object);
3244       object = parent(object, path);
3245       var func = object == null ? object : object[toKey(last(path))];
3246       return func == null ? undefined : apply(func, object, args);
3247     }
3248
3249     /**
3250      * The base implementation of `_.isArguments`.
3251      *
3252      * @private
3253      * @param {*} value The value to check.
3254      * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3255      */
3256     function baseIsArguments(value) {
3257       return isObjectLike(value) && baseGetTag(value) == argsTag;
3258     }
3259
3260     /**
3261      * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3262      *
3263      * @private
3264      * @param {*} value The value to check.
3265      * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3266      */
3267     function baseIsArrayBuffer(value) {
3268       return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3269     }
3270
3271     /**
3272      * The base implementation of `_.isDate` without Node.js optimizations.
3273      *
3274      * @private
3275      * @param {*} value The value to check.
3276      * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3277      */
3278     function baseIsDate(value) {
3279       return isObjectLike(value) && baseGetTag(value) == dateTag;
3280     }
3281
3282     /**
3283      * The base implementation of `_.isEqual` which supports partial comparisons
3284      * and tracks traversed objects.
3285      *
3286      * @private
3287      * @param {*} value The value to compare.
3288      * @param {*} other The other value to compare.
3289      * @param {boolean} bitmask The bitmask flags.
3290      *  1 - Unordered comparison
3291      *  2 - Partial comparison
3292      * @param {Function} [customizer] The function to customize comparisons.
3293      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3294      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3295      */
3296     function baseIsEqual(value, other, bitmask, customizer, stack) {
3297       if (value === other) {
3298         return true;
3299       }
3300       if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
3301         return value !== value && other !== other;
3302       }
3303       return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3304     }
3305
3306     /**
3307      * A specialized version of `baseIsEqual` for arrays and objects which performs
3308      * deep comparisons and tracks traversed objects enabling objects with circular
3309      * references to be compared.
3310      *
3311      * @private
3312      * @param {Object} object The object to compare.
3313      * @param {Object} other The other object to compare.
3314      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3315      * @param {Function} customizer The function to customize comparisons.
3316      * @param {Function} equalFunc The function to determine equivalents of values.
3317      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3318      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3319      */
3320     function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3321       var objIsArr = isArray(object),
3322           othIsArr = isArray(other),
3323           objTag = objIsArr ? arrayTag : getTag(object),
3324           othTag = othIsArr ? arrayTag : getTag(other);
3325
3326       objTag = objTag == argsTag ? objectTag : objTag;
3327       othTag = othTag == argsTag ? objectTag : othTag;
3328
3329       var objIsObj = objTag == objectTag,
3330           othIsObj = othTag == objectTag,
3331           isSameTag = objTag == othTag;
3332
3333       if (isSameTag && isBuffer(object)) {
3334         if (!isBuffer(other)) {
3335           return false;
3336         }
3337         objIsArr = true;
3338         objIsObj = false;
3339       }
3340       if (isSameTag && !objIsObj) {
3341         stack || (stack = new Stack);
3342         return (objIsArr || isTypedArray(object))
3343           ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3344           : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3345       }
3346       if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3347         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3348             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3349
3350         if (objIsWrapped || othIsWrapped) {
3351           var objUnwrapped = objIsWrapped ? object.value() : object,
3352               othUnwrapped = othIsWrapped ? other.value() : other;
3353
3354           stack || (stack = new Stack);
3355           return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3356         }
3357       }
3358       if (!isSameTag) {
3359         return false;
3360       }
3361       stack || (stack = new Stack);
3362       return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3363     }
3364
3365     /**
3366      * The base implementation of `_.isMap` without Node.js optimizations.
3367      *
3368      * @private
3369      * @param {*} value The value to check.
3370      * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3371      */
3372     function baseIsMap(value) {
3373       return isObjectLike(value) && getTag(value) == mapTag;
3374     }
3375
3376     /**
3377      * The base implementation of `_.isMatch` without support for iteratee shorthands.
3378      *
3379      * @private
3380      * @param {Object} object The object to inspect.
3381      * @param {Object} source The object of property values to match.
3382      * @param {Array} matchData The property names, values, and compare flags to match.
3383      * @param {Function} [customizer] The function to customize comparisons.
3384      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3385      */
3386     function baseIsMatch(object, source, matchData, customizer) {
3387       var index = matchData.length,
3388           length = index,
3389           noCustomizer = !customizer;
3390
3391       if (object == null) {
3392         return !length;
3393       }
3394       object = Object(object);
3395       while (index--) {
3396         var data = matchData[index];
3397         if ((noCustomizer && data[2])
3398               ? data[1] !== object[data[0]]
3399               : !(data[0] in object)
3400             ) {
3401           return false;
3402         }
3403       }
3404       while (++index < length) {
3405         data = matchData[index];
3406         var key = data[0],
3407             objValue = object[key],
3408             srcValue = data[1];
3409
3410         if (noCustomizer && data[2]) {
3411           if (objValue === undefined && !(key in object)) {
3412             return false;
3413           }
3414         } else {
3415           var stack = new Stack;
3416           if (customizer) {
3417             var result = customizer(objValue, srcValue, key, object, source, stack);
3418           }
3419           if (!(result === undefined
3420                 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3421                 : result
3422               )) {
3423             return false;
3424           }
3425         }
3426       }
3427       return true;
3428     }
3429
3430     /**
3431      * The base implementation of `_.isNative` without bad shim checks.
3432      *
3433      * @private
3434      * @param {*} value The value to check.
3435      * @returns {boolean} Returns `true` if `value` is a native function,
3436      *  else `false`.
3437      */
3438     function baseIsNative(value) {
3439       if (!isObject(value) || isMasked(value)) {
3440         return false;
3441       }
3442       var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3443       return pattern.test(toSource(value));
3444     }
3445
3446     /**
3447      * The base implementation of `_.isRegExp` without Node.js optimizations.
3448      *
3449      * @private
3450      * @param {*} value The value to check.
3451      * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3452      */
3453     function baseIsRegExp(value) {
3454       return isObjectLike(value) && baseGetTag(value) == regexpTag;
3455     }
3456
3457     /**
3458      * The base implementation of `_.isSet` without Node.js optimizations.
3459      *
3460      * @private
3461      * @param {*} value The value to check.
3462      * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3463      */
3464     function baseIsSet(value) {
3465       return isObjectLike(value) && getTag(value) == setTag;
3466     }
3467
3468     /**
3469      * The base implementation of `_.isTypedArray` without Node.js optimizations.
3470      *
3471      * @private
3472      * @param {*} value The value to check.
3473      * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3474      */
3475     function baseIsTypedArray(value) {
3476       return isObjectLike(value) &&
3477         isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3478     }
3479
3480     /**
3481      * The base implementation of `_.iteratee`.
3482      *
3483      * @private
3484      * @param {*} [value=_.identity] The value to convert to an iteratee.
3485      * @returns {Function} Returns the iteratee.
3486      */
3487     function baseIteratee(value) {
3488       // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3489       // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3490       if (typeof value == 'function') {
3491         return value;
3492       }
3493       if (value == null) {
3494         return identity;
3495       }
3496       if (typeof value == 'object') {
3497         return isArray(value)
3498           ? baseMatchesProperty(value[0], value[1])
3499           : baseMatches(value);
3500       }
3501       return property(value);
3502     }
3503
3504     /**
3505      * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3506      *
3507      * @private
3508      * @param {Object} object The object to query.
3509      * @returns {Array} Returns the array of property names.
3510      */
3511     function baseKeys(object) {
3512       if (!isPrototype(object)) {
3513         return nativeKeys(object);
3514       }
3515       var result = [];
3516       for (var key in Object(object)) {
3517         if (hasOwnProperty.call(object, key) && key != 'constructor') {
3518           result.push(key);
3519         }
3520       }
3521       return result;
3522     }
3523
3524     /**
3525      * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3526      *
3527      * @private
3528      * @param {Object} object The object to query.
3529      * @returns {Array} Returns the array of property names.
3530      */
3531     function baseKeysIn(object) {
3532       if (!isObject(object)) {
3533         return nativeKeysIn(object);
3534       }
3535       var isProto = isPrototype(object),
3536           result = [];
3537
3538       for (var key in object) {
3539         if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3540           result.push(key);
3541         }
3542       }
3543       return result;
3544     }
3545
3546     /**
3547      * The base implementation of `_.lt` which doesn't coerce arguments.
3548      *
3549      * @private
3550      * @param {*} value The value to compare.
3551      * @param {*} other The other value to compare.
3552      * @returns {boolean} Returns `true` if `value` is less than `other`,
3553      *  else `false`.
3554      */
3555     function baseLt(value, other) {
3556       return value < other;
3557     }
3558
3559     /**
3560      * The base implementation of `_.map` without support for iteratee shorthands.
3561      *
3562      * @private
3563      * @param {Array|Object} collection The collection to iterate over.
3564      * @param {Function} iteratee The function invoked per iteration.
3565      * @returns {Array} Returns the new mapped array.
3566      */
3567     function baseMap(collection, iteratee) {
3568       var index = -1,
3569           result = isArrayLike(collection) ? Array(collection.length) : [];
3570
3571       baseEach(collection, function(value, key, collection) {
3572         result[++index] = iteratee(value, key, collection);
3573       });
3574       return result;
3575     }
3576
3577     /**
3578      * The base implementation of `_.matches` which doesn't clone `source`.
3579      *
3580      * @private
3581      * @param {Object} source The object of property values to match.
3582      * @returns {Function} Returns the new spec function.
3583      */
3584     function baseMatches(source) {
3585       var matchData = getMatchData(source);
3586       if (matchData.length == 1 && matchData[0][2]) {
3587         return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3588       }
3589       return function(object) {
3590         return object === source || baseIsMatch(object, source, matchData);
3591       };
3592     }
3593
3594     /**
3595      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3596      *
3597      * @private
3598      * @param {string} path The path of the property to get.
3599      * @param {*} srcValue The value to match.
3600      * @returns {Function} Returns the new spec function.
3601      */
3602     function baseMatchesProperty(path, srcValue) {
3603       if (isKey(path) && isStrictComparable(srcValue)) {
3604         return matchesStrictComparable(toKey(path), srcValue);
3605       }
3606       return function(object) {
3607         var objValue = get(object, path);
3608         return (objValue === undefined && objValue === srcValue)
3609           ? hasIn(object, path)
3610           : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3611       };
3612     }
3613
3614     /**
3615      * The base implementation of `_.merge` without support for multiple sources.
3616      *
3617      * @private
3618      * @param {Object} object The destination object.
3619      * @param {Object} source The source object.
3620      * @param {number} srcIndex The index of `source`.
3621      * @param {Function} [customizer] The function to customize merged values.
3622      * @param {Object} [stack] Tracks traversed source values and their merged
3623      *  counterparts.
3624      */
3625     function baseMerge(object, source, srcIndex, customizer, stack) {
3626       if (object === source) {
3627         return;
3628       }
3629       baseFor(source, function(srcValue, key) {
3630         if (isObject(srcValue)) {
3631           stack || (stack = new Stack);
3632           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3633         }
3634         else {
3635           var newValue = customizer
3636             ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3637             : undefined;
3638
3639           if (newValue === undefined) {
3640             newValue = srcValue;
3641           }
3642           assignMergeValue(object, key, newValue);
3643         }
3644       }, keysIn);
3645     }
3646
3647     /**
3648      * A specialized version of `baseMerge` for arrays and objects which performs
3649      * deep merges and tracks traversed objects enabling objects with circular
3650      * references to be merged.
3651      *
3652      * @private
3653      * @param {Object} object The destination object.
3654      * @param {Object} source The source object.
3655      * @param {string} key The key of the value to merge.
3656      * @param {number} srcIndex The index of `source`.
3657      * @param {Function} mergeFunc The function to merge values.
3658      * @param {Function} [customizer] The function to customize assigned values.
3659      * @param {Object} [stack] Tracks traversed source values and their merged
3660      *  counterparts.
3661      */
3662     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3663       var objValue = object[key],
3664           srcValue = source[key],
3665           stacked = stack.get(srcValue);
3666
3667       if (stacked) {
3668         assignMergeValue(object, key, stacked);
3669         return;
3670       }
3671       var newValue = customizer
3672         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3673         : undefined;
3674
3675       var isCommon = newValue === undefined;
3676
3677       if (isCommon) {
3678         var isArr = isArray(srcValue),
3679             isBuff = !isArr && isBuffer(srcValue),
3680             isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3681
3682         newValue = srcValue;
3683         if (isArr || isBuff || isTyped) {
3684           if (isArray(objValue)) {
3685             newValue = objValue;
3686           }
3687           else if (isArrayLikeObject(objValue)) {
3688             newValue = copyArray(objValue);
3689           }
3690           else if (isBuff) {
3691             isCommon = false;
3692             newValue = cloneBuffer(srcValue, true);
3693           }
3694           else if (isTyped) {
3695             isCommon = false;
3696             newValue = cloneTypedArray(srcValue, true);
3697           }
3698           else {
3699             newValue = [];
3700           }
3701         }
3702         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3703           newValue = objValue;
3704           if (isArguments(objValue)) {
3705             newValue = toPlainObject(objValue);
3706           }
3707           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3708             newValue = initCloneObject(srcValue);
3709           }
3710         }
3711         else {
3712           isCommon = false;
3713         }
3714       }
3715       if (isCommon) {
3716         // Recursively merge objects and arrays (susceptible to call stack limits).
3717         stack.set(srcValue, newValue);
3718         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3719         stack['delete'](srcValue);
3720       }
3721       assignMergeValue(object, key, newValue);
3722     }
3723
3724     /**
3725      * The base implementation of `_.nth` which doesn't coerce arguments.
3726      *
3727      * @private
3728      * @param {Array} array The array to query.
3729      * @param {number} n The index of the element to return.
3730      * @returns {*} Returns the nth element of `array`.
3731      */
3732     function baseNth(array, n) {
3733       var length = array.length;
3734       if (!length) {
3735         return;
3736       }
3737       n += n < 0 ? length : 0;
3738       return isIndex(n, length) ? array[n] : undefined;
3739     }
3740
3741     /**
3742      * The base implementation of `_.orderBy` without param guards.
3743      *
3744      * @private
3745      * @param {Array|Object} collection The collection to iterate over.
3746      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3747      * @param {string[]} orders The sort orders of `iteratees`.
3748      * @returns {Array} Returns the new sorted array.
3749      */
3750     function baseOrderBy(collection, iteratees, orders) {
3751       var index = -1;
3752       iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3753
3754       var result = baseMap(collection, function(value, key, collection) {
3755         var criteria = arrayMap(iteratees, function(iteratee) {
3756           return iteratee(value);
3757         });
3758         return { 'criteria': criteria, 'index': ++index, 'value': value };
3759       });
3760
3761       return baseSortBy(result, function(object, other) {
3762         return compareMultiple(object, other, orders);
3763       });
3764     }
3765
3766     /**
3767      * The base implementation of `_.pick` without support for individual
3768      * property identifiers.
3769      *
3770      * @private
3771      * @param {Object} object The source object.
3772      * @param {string[]} paths The property paths to pick.
3773      * @returns {Object} Returns the new object.
3774      */
3775     function basePick(object, paths) {
3776       return basePickBy(object, paths, function(value, path) {
3777         return hasIn(object, path);
3778       });
3779     }
3780
3781     /**
3782      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3783      *
3784      * @private
3785      * @param {Object} object The source object.
3786      * @param {string[]} paths The property paths to pick.
3787      * @param {Function} predicate The function invoked per property.
3788      * @returns {Object} Returns the new object.
3789      */
3790     function basePickBy(object, paths, predicate) {
3791       var index = -1,
3792           length = paths.length,
3793           result = {};
3794
3795       while (++index < length) {
3796         var path = paths[index],
3797             value = baseGet(object, path);
3798
3799         if (predicate(value, path)) {
3800           baseSet(result, castPath(path, object), value);
3801         }
3802       }
3803       return result;
3804     }
3805
3806     /**
3807      * A specialized version of `baseProperty` which supports deep paths.
3808      *
3809      * @private
3810      * @param {Array|string} path The path of the property to get.
3811      * @returns {Function} Returns the new accessor function.
3812      */
3813     function basePropertyDeep(path) {
3814       return function(object) {
3815         return baseGet(object, path);
3816       };
3817     }
3818
3819     /**
3820      * The base implementation of `_.pullAllBy` without support for iteratee
3821      * shorthands.
3822      *
3823      * @private
3824      * @param {Array} array The array to modify.
3825      * @param {Array} values The values to remove.
3826      * @param {Function} [iteratee] The iteratee invoked per element.
3827      * @param {Function} [comparator] The comparator invoked per element.
3828      * @returns {Array} Returns `array`.
3829      */
3830     function basePullAll(array, values, iteratee, comparator) {
3831       var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3832           index = -1,
3833           length = values.length,
3834           seen = array;
3835
3836       if (array === values) {
3837         values = copyArray(values);
3838       }
3839       if (iteratee) {
3840         seen = arrayMap(array, baseUnary(iteratee));
3841       }
3842       while (++index < length) {
3843         var fromIndex = 0,
3844             value = values[index],
3845             computed = iteratee ? iteratee(value) : value;
3846
3847         while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3848           if (seen !== array) {
3849             splice.call(seen, fromIndex, 1);
3850           }
3851           splice.call(array, fromIndex, 1);
3852         }
3853       }
3854       return array;
3855     }
3856
3857     /**
3858      * The base implementation of `_.pullAt` without support for individual
3859      * indexes or capturing the removed elements.
3860      *
3861      * @private
3862      * @param {Array} array The array to modify.
3863      * @param {number[]} indexes The indexes of elements to remove.
3864      * @returns {Array} Returns `array`.
3865      */
3866     function basePullAt(array, indexes) {
3867       var length = array ? indexes.length : 0,
3868           lastIndex = length - 1;
3869
3870       while (length--) {
3871         var index = indexes[length];
3872         if (length == lastIndex || index !== previous) {
3873           var previous = index;
3874           if (isIndex(index)) {
3875             splice.call(array, index, 1);
3876           } else {
3877             baseUnset(array, index);
3878           }
3879         }
3880       }
3881       return array;
3882     }
3883
3884     /**
3885      * The base implementation of `_.random` without support for returning
3886      * floating-point numbers.
3887      *
3888      * @private
3889      * @param {number} lower The lower bound.
3890      * @param {number} upper The upper bound.
3891      * @returns {number} Returns the random number.
3892      */
3893     function baseRandom(lower, upper) {
3894       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3895     }
3896
3897     /**
3898      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3899      * coerce arguments.
3900      *
3901      * @private
3902      * @param {number} start The start of the range.
3903      * @param {number} end The end of the range.
3904      * @param {number} step The value to increment or decrement by.
3905      * @param {boolean} [fromRight] Specify iterating from right to left.
3906      * @returns {Array} Returns the range of numbers.
3907      */
3908     function baseRange(start, end, step, fromRight) {
3909       var index = -1,
3910           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3911           result = Array(length);
3912
3913       while (length--) {
3914         result[fromRight ? length : ++index] = start;
3915         start += step;
3916       }
3917       return result;
3918     }
3919
3920     /**
3921      * The base implementation of `_.repeat` which doesn't coerce arguments.
3922      *
3923      * @private
3924      * @param {string} string The string to repeat.
3925      * @param {number} n The number of times to repeat the string.
3926      * @returns {string} Returns the repeated string.
3927      */
3928     function baseRepeat(string, n) {
3929       var result = '';
3930       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3931         return result;
3932       }
3933       // Leverage the exponentiation by squaring algorithm for a faster repeat.
3934       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3935       do {
3936         if (n % 2) {
3937           result += string;
3938         }
3939         n = nativeFloor(n / 2);
3940         if (n) {
3941           string += string;
3942         }
3943       } while (n);
3944
3945       return result;
3946     }
3947
3948     /**
3949      * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3950      *
3951      * @private
3952      * @param {Function} func The function to apply a rest parameter to.
3953      * @param {number} [start=func.length-1] The start position of the rest parameter.
3954      * @returns {Function} Returns the new function.
3955      */
3956     function baseRest(func, start) {
3957       return setToString(overRest(func, start, identity), func + '');
3958     }
3959
3960     /**
3961      * The base implementation of `_.sample`.
3962      *
3963      * @private
3964      * @param {Array|Object} collection The collection to sample.
3965      * @returns {*} Returns the random element.
3966      */
3967     function baseSample(collection) {
3968       return arraySample(values(collection));
3969     }
3970
3971     /**
3972      * The base implementation of `_.sampleSize` without param guards.
3973      *
3974      * @private
3975      * @param {Array|Object} collection The collection to sample.
3976      * @param {number} n The number of elements to sample.
3977      * @returns {Array} Returns the random elements.
3978      */
3979     function baseSampleSize(collection, n) {
3980       var array = values(collection);
3981       return shuffleSelf(array, baseClamp(n, 0, array.length));
3982     }
3983
3984     /**
3985      * The base implementation of `_.set`.
3986      *
3987      * @private
3988      * @param {Object} object The object to modify.
3989      * @param {Array|string} path The path of the property to set.
3990      * @param {*} value The value to set.
3991      * @param {Function} [customizer] The function to customize path creation.
3992      * @returns {Object} Returns `object`.
3993      */
3994     function baseSet(object, path, value, customizer) {
3995       if (!isObject(object)) {
3996         return object;
3997       }
3998       path = castPath(path, object);
3999
4000       var index = -1,
4001           length = path.length,
4002           lastIndex = length - 1,
4003           nested = object;
4004
4005       while (nested != null && ++index < length) {
4006         var key = toKey(path[index]),
4007             newValue = value;
4008
4009         if (index != lastIndex) {
4010           var objValue = nested[key];
4011           newValue = customizer ? customizer(objValue, key, nested) : undefined;
4012           if (newValue === undefined) {
4013             newValue = isObject(objValue)
4014               ? objValue
4015               : (isIndex(path[index + 1]) ? [] : {});
4016           }
4017         }
4018         assignValue(nested, key, newValue);
4019         nested = nested[key];
4020       }
4021       return object;
4022     }
4023
4024     /**
4025      * The base implementation of `setData` without support for hot loop shorting.
4026      *
4027      * @private
4028      * @param {Function} func The function to associate metadata with.
4029      * @param {*} data The metadata.
4030      * @returns {Function} Returns `func`.
4031      */
4032     var baseSetData = !metaMap ? identity : function(func, data) {
4033       metaMap.set(func, data);
4034       return func;
4035     };
4036
4037     /**
4038      * The base implementation of `setToString` without support for hot loop shorting.
4039      *
4040      * @private
4041      * @param {Function} func The function to modify.
4042      * @param {Function} string The `toString` result.
4043      * @returns {Function} Returns `func`.
4044      */
4045     var baseSetToString = !defineProperty ? identity : function(func, string) {
4046       return defineProperty(func, 'toString', {
4047         'configurable': true,
4048         'enumerable': false,
4049         'value': constant(string),
4050         'writable': true
4051       });
4052     };
4053
4054     /**
4055      * The base implementation of `_.shuffle`.
4056      *
4057      * @private
4058      * @param {Array|Object} collection The collection to shuffle.
4059      * @returns {Array} Returns the new shuffled array.
4060      */
4061     function baseShuffle(collection) {
4062       return shuffleSelf(values(collection));
4063     }
4064
4065     /**
4066      * The base implementation of `_.slice` without an iteratee call guard.
4067      *
4068      * @private
4069      * @param {Array} array The array to slice.
4070      * @param {number} [start=0] The start position.
4071      * @param {number} [end=array.length] The end position.
4072      * @returns {Array} Returns the slice of `array`.
4073      */
4074     function baseSlice(array, start, end) {
4075       var index = -1,
4076           length = array.length;
4077
4078       if (start < 0) {
4079         start = -start > length ? 0 : (length + start);
4080       }
4081       end = end > length ? length : end;
4082       if (end < 0) {
4083         end += length;
4084       }
4085       length = start > end ? 0 : ((end - start) >>> 0);
4086       start >>>= 0;
4087
4088       var result = Array(length);
4089       while (++index < length) {
4090         result[index] = array[index + start];
4091       }
4092       return result;
4093     }
4094
4095     /**
4096      * The base implementation of `_.some` without support for iteratee shorthands.
4097      *
4098      * @private
4099      * @param {Array|Object} collection The collection to iterate over.
4100      * @param {Function} predicate The function invoked per iteration.
4101      * @returns {boolean} Returns `true` if any element passes the predicate check,
4102      *  else `false`.
4103      */
4104     function baseSome(collection, predicate) {
4105       var result;
4106
4107       baseEach(collection, function(value, index, collection) {
4108         result = predicate(value, index, collection);
4109         return !result;
4110       });
4111       return !!result;
4112     }
4113
4114     /**
4115      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4116      * performs a binary search of `array` to determine the index at which `value`
4117      * should be inserted into `array` in order to maintain its sort order.
4118      *
4119      * @private
4120      * @param {Array} array The sorted array to inspect.
4121      * @param {*} value The value to evaluate.
4122      * @param {boolean} [retHighest] Specify returning the highest qualified index.
4123      * @returns {number} Returns the index at which `value` should be inserted
4124      *  into `array`.
4125      */
4126     function baseSortedIndex(array, value, retHighest) {
4127       var low = 0,
4128           high = array == null ? low : array.length;
4129
4130       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4131         while (low < high) {
4132           var mid = (low + high) >>> 1,
4133               computed = array[mid];
4134
4135           if (computed !== null && !isSymbol(computed) &&
4136               (retHighest ? (computed <= value) : (computed < value))) {
4137             low = mid + 1;
4138           } else {
4139             high = mid;
4140           }
4141         }
4142         return high;
4143       }
4144       return baseSortedIndexBy(array, value, identity, retHighest);
4145     }
4146
4147     /**
4148      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4149      * which invokes `iteratee` for `value` and each element of `array` to compute
4150      * their sort ranking. The iteratee is invoked with one argument; (value).
4151      *
4152      * @private
4153      * @param {Array} array The sorted array to inspect.
4154      * @param {*} value The value to evaluate.
4155      * @param {Function} iteratee The iteratee invoked per element.
4156      * @param {boolean} [retHighest] Specify returning the highest qualified index.
4157      * @returns {number} Returns the index at which `value` should be inserted
4158      *  into `array`.
4159      */
4160     function baseSortedIndexBy(array, value, iteratee, retHighest) {
4161       value = iteratee(value);
4162
4163       var low = 0,
4164           high = array == null ? 0 : array.length,
4165           valIsNaN = value !== value,
4166           valIsNull = value === null,
4167           valIsSymbol = isSymbol(value),
4168           valIsUndefined = value === undefined;
4169
4170       while (low < high) {
4171         var mid = nativeFloor((low + high) / 2),
4172             computed = iteratee(array[mid]),
4173             othIsDefined = computed !== undefined,
4174             othIsNull = computed === null,
4175             othIsReflexive = computed === computed,
4176             othIsSymbol = isSymbol(computed);
4177
4178         if (valIsNaN) {
4179           var setLow = retHighest || othIsReflexive;
4180         } else if (valIsUndefined) {
4181           setLow = othIsReflexive && (retHighest || othIsDefined);
4182         } else if (valIsNull) {
4183           setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4184         } else if (valIsSymbol) {
4185           setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4186         } else if (othIsNull || othIsSymbol) {
4187           setLow = false;
4188         } else {
4189           setLow = retHighest ? (computed <= value) : (computed < value);
4190         }
4191         if (setLow) {
4192           low = mid + 1;
4193         } else {
4194           high = mid;
4195         }
4196       }
4197       return nativeMin(high, MAX_ARRAY_INDEX);
4198     }
4199
4200     /**
4201      * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4202      * support for iteratee shorthands.
4203      *
4204      * @private
4205      * @param {Array} array The array to inspect.
4206      * @param {Function} [iteratee] The iteratee invoked per element.
4207      * @returns {Array} Returns the new duplicate free array.
4208      */
4209     function baseSortedUniq(array, iteratee) {
4210       var index = -1,
4211           length = array.length,
4212           resIndex = 0,
4213           result = [];
4214
4215       while (++index < length) {
4216         var value = array[index],
4217             computed = iteratee ? iteratee(value) : value;
4218
4219         if (!index || !eq(computed, seen)) {
4220           var seen = computed;
4221           result[resIndex++] = value === 0 ? 0 : value;
4222         }
4223       }
4224       return result;
4225     }
4226
4227     /**
4228      * The base implementation of `_.toNumber` which doesn't ensure correct
4229      * conversions of binary, hexadecimal, or octal string values.
4230      *
4231      * @private
4232      * @param {*} value The value to process.
4233      * @returns {number} Returns the number.
4234      */
4235     function baseToNumber(value) {
4236       if (typeof value == 'number') {
4237         return value;
4238       }
4239       if (isSymbol(value)) {
4240         return NAN;
4241       }
4242       return +value;
4243     }
4244
4245     /**
4246      * The base implementation of `_.toString` which doesn't convert nullish
4247      * values to empty strings.
4248      *
4249      * @private
4250      * @param {*} value The value to process.
4251      * @returns {string} Returns the string.
4252      */
4253     function baseToString(value) {
4254       // Exit early for strings to avoid a performance hit in some environments.
4255       if (typeof value == 'string') {
4256         return value;
4257       }
4258       if (isArray(value)) {
4259         // Recursively convert values (susceptible to call stack limits).
4260         return arrayMap(value, baseToString) + '';
4261       }
4262       if (isSymbol(value)) {
4263         return symbolToString ? symbolToString.call(value) : '';
4264       }
4265       var result = (value + '');
4266       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4267     }
4268
4269     /**
4270      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4271      *
4272      * @private
4273      * @param {Array} array The array to inspect.
4274      * @param {Function} [iteratee] The iteratee invoked per element.
4275      * @param {Function} [comparator] The comparator invoked per element.
4276      * @returns {Array} Returns the new duplicate free array.
4277      */
4278     function baseUniq(array, iteratee, comparator) {
4279       var index = -1,
4280           includes = arrayIncludes,
4281           length = array.length,
4282           isCommon = true,
4283           result = [],
4284           seen = result;
4285
4286       if (comparator) {
4287         isCommon = false;
4288         includes = arrayIncludesWith;
4289       }
4290       else if (length >= LARGE_ARRAY_SIZE) {
4291         var set = iteratee ? null : createSet(array);
4292         if (set) {
4293           return setToArray(set);
4294         }
4295         isCommon = false;
4296         includes = cacheHas;
4297         seen = new SetCache;
4298       }
4299       else {
4300         seen = iteratee ? [] : result;
4301       }
4302       outer:
4303       while (++index < length) {
4304         var value = array[index],
4305             computed = iteratee ? iteratee(value) : value;
4306
4307         value = (comparator || value !== 0) ? value : 0;
4308         if (isCommon && computed === computed) {
4309           var seenIndex = seen.length;
4310           while (seenIndex--) {
4311             if (seen[seenIndex] === computed) {
4312               continue outer;
4313             }
4314           }
4315           if (iteratee) {
4316             seen.push(computed);
4317           }
4318           result.push(value);
4319         }
4320         else if (!includes(seen, computed, comparator)) {
4321           if (seen !== result) {
4322             seen.push(computed);
4323           }
4324           result.push(value);
4325         }
4326       }
4327       return result;
4328     }
4329
4330     /**
4331      * The base implementation of `_.unset`.
4332      *
4333      * @private
4334      * @param {Object} object The object to modify.
4335      * @param {Array|string} path The property path to unset.
4336      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4337      */
4338     function baseUnset(object, path) {
4339       path = castPath(path, object);
4340       object = parent(object, path);
4341       return object == null || delete object[toKey(last(path))];
4342     }
4343
4344     /**
4345      * The base implementation of `_.update`.
4346      *
4347      * @private
4348      * @param {Object} object The object to modify.
4349      * @param {Array|string} path The path of the property to update.
4350      * @param {Function} updater The function to produce the updated value.
4351      * @param {Function} [customizer] The function to customize path creation.
4352      * @returns {Object} Returns `object`.
4353      */
4354     function baseUpdate(object, path, updater, customizer) {
4355       return baseSet(object, path, updater(baseGet(object, path)), customizer);
4356     }
4357
4358     /**
4359      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4360      * without support for iteratee shorthands.
4361      *
4362      * @private
4363      * @param {Array} array The array to query.
4364      * @param {Function} predicate The function invoked per iteration.
4365      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4366      * @param {boolean} [fromRight] Specify iterating from right to left.
4367      * @returns {Array} Returns the slice of `array`.
4368      */
4369     function baseWhile(array, predicate, isDrop, fromRight) {
4370       var length = array.length,
4371           index = fromRight ? length : -1;
4372
4373       while ((fromRight ? index-- : ++index < length) &&
4374         predicate(array[index], index, array)) {}
4375
4376       return isDrop
4377         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4378         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4379     }
4380
4381     /**
4382      * The base implementation of `wrapperValue` which returns the result of
4383      * performing a sequence of actions on the unwrapped `value`, where each
4384      * successive action is supplied the return value of the previous.
4385      *
4386      * @private
4387      * @param {*} value The unwrapped value.
4388      * @param {Array} actions Actions to perform to resolve the unwrapped value.
4389      * @returns {*} Returns the resolved value.
4390      */
4391     function baseWrapperValue(value, actions) {
4392       var result = value;
4393       if (result instanceof LazyWrapper) {
4394         result = result.value();
4395       }
4396       return arrayReduce(actions, function(result, action) {
4397         return action.func.apply(action.thisArg, arrayPush([result], action.args));
4398       }, result);
4399     }
4400
4401     /**
4402      * The base implementation of methods like `_.xor`, without support for
4403      * iteratee shorthands, that accepts an array of arrays to inspect.
4404      *
4405      * @private
4406      * @param {Array} arrays The arrays to inspect.
4407      * @param {Function} [iteratee] The iteratee invoked per element.
4408      * @param {Function} [comparator] The comparator invoked per element.
4409      * @returns {Array} Returns the new array of values.
4410      */
4411     function baseXor(arrays, iteratee, comparator) {
4412       var length = arrays.length;
4413       if (length < 2) {
4414         return length ? baseUniq(arrays[0]) : [];
4415       }
4416       var index = -1,
4417           result = Array(length);
4418
4419       while (++index < length) {
4420         var array = arrays[index],
4421             othIndex = -1;
4422
4423         while (++othIndex < length) {
4424           if (othIndex != index) {
4425             result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4426           }
4427         }
4428       }
4429       return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4430     }
4431
4432     /**
4433      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4434      *
4435      * @private
4436      * @param {Array} props The property identifiers.
4437      * @param {Array} values The property values.
4438      * @param {Function} assignFunc The function to assign values.
4439      * @returns {Object} Returns the new object.
4440      */
4441     function baseZipObject(props, values, assignFunc) {
4442       var index = -1,
4443           length = props.length,
4444           valsLength = values.length,
4445           result = {};
4446
4447       while (++index < length) {
4448         var value = index < valsLength ? values[index] : undefined;
4449         assignFunc(result, props[index], value);
4450       }
4451       return result;
4452     }
4453
4454     /**
4455      * Casts `value` to an empty array if it's not an array like object.
4456      *
4457      * @private
4458      * @param {*} value The value to inspect.
4459      * @returns {Array|Object} Returns the cast array-like object.
4460      */
4461     function castArrayLikeObject(value) {
4462       return isArrayLikeObject(value) ? value : [];
4463     }
4464
4465     /**
4466      * Casts `value` to `identity` if it's not a function.
4467      *
4468      * @private
4469      * @param {*} value The value to inspect.
4470      * @returns {Function} Returns cast function.
4471      */
4472     function castFunction(value) {
4473       return typeof value == 'function' ? value : identity;
4474     }
4475
4476     /**
4477      * Casts `value` to a path array if it's not one.
4478      *
4479      * @private
4480      * @param {*} value The value to inspect.
4481      * @param {Object} [object] The object to query keys on.
4482      * @returns {Array} Returns the cast property path array.
4483      */
4484     function castPath(value, object) {
4485       if (isArray(value)) {
4486         return value;
4487       }
4488       return isKey(value, object) ? [value] : stringToPath(toString(value));
4489     }
4490
4491     /**
4492      * A `baseRest` alias which can be replaced with `identity` by module
4493      * replacement plugins.
4494      *
4495      * @private
4496      * @type {Function}
4497      * @param {Function} func The function to apply a rest parameter to.
4498      * @returns {Function} Returns the new function.
4499      */
4500     var castRest = baseRest;
4501
4502     /**
4503      * Casts `array` to a slice if it's needed.
4504      *
4505      * @private
4506      * @param {Array} array The array to inspect.
4507      * @param {number} start The start position.
4508      * @param {number} [end=array.length] The end position.
4509      * @returns {Array} Returns the cast slice.
4510      */
4511     function castSlice(array, start, end) {
4512       var length = array.length;
4513       end = end === undefined ? length : end;
4514       return (!start && end >= length) ? array : baseSlice(array, start, end);
4515     }
4516
4517     /**
4518      * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4519      *
4520      * @private
4521      * @param {number|Object} id The timer id or timeout object of the timer to clear.
4522      */
4523     var clearTimeout = ctxClearTimeout || function(id) {
4524       return root.clearTimeout(id);
4525     };
4526
4527     /**
4528      * Creates a clone of  `buffer`.
4529      *
4530      * @private
4531      * @param {Buffer} buffer The buffer to clone.
4532      * @param {boolean} [isDeep] Specify a deep clone.
4533      * @returns {Buffer} Returns the cloned buffer.
4534      */
4535     function cloneBuffer(buffer, isDeep) {
4536       if (isDeep) {
4537         return buffer.slice();
4538       }
4539       var length = buffer.length,
4540           result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4541
4542       buffer.copy(result);
4543       return result;
4544     }
4545
4546     /**
4547      * Creates a clone of `arrayBuffer`.
4548      *
4549      * @private
4550      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4551      * @returns {ArrayBuffer} Returns the cloned array buffer.
4552      */
4553     function cloneArrayBuffer(arrayBuffer) {
4554       var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4555       new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4556       return result;
4557     }
4558
4559     /**
4560      * Creates a clone of `dataView`.
4561      *
4562      * @private
4563      * @param {Object} dataView The data view to clone.
4564      * @param {boolean} [isDeep] Specify a deep clone.
4565      * @returns {Object} Returns the cloned data view.
4566      */
4567     function cloneDataView(dataView, isDeep) {
4568       var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4569       return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4570     }
4571
4572     /**
4573      * Creates a clone of `map`.
4574      *
4575      * @private
4576      * @param {Object} map The map to clone.
4577      * @param {Function} cloneFunc The function to clone values.
4578      * @param {boolean} [isDeep] Specify a deep clone.
4579      * @returns {Object} Returns the cloned map.
4580      */
4581     function cloneMap(map, isDeep, cloneFunc) {
4582       var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
4583       return arrayReduce(array, addMapEntry, new map.constructor);
4584     }
4585
4586     /**
4587      * Creates a clone of `regexp`.
4588      *
4589      * @private
4590      * @param {Object} regexp The regexp to clone.
4591      * @returns {Object} Returns the cloned regexp.
4592      */
4593     function cloneRegExp(regexp) {
4594       var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4595       result.lastIndex = regexp.lastIndex;
4596       return result;
4597     }
4598
4599     /**
4600      * Creates a clone of `set`.
4601      *
4602      * @private
4603      * @param {Object} set The set to clone.
4604      * @param {Function} cloneFunc The function to clone values.
4605      * @param {boolean} [isDeep] Specify a deep clone.
4606      * @returns {Object} Returns the cloned set.
4607      */
4608     function cloneSet(set, isDeep, cloneFunc) {
4609       var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
4610       return arrayReduce(array, addSetEntry, new set.constructor);
4611     }
4612
4613     /**
4614      * Creates a clone of the `symbol` object.
4615      *
4616      * @private
4617      * @param {Object} symbol The symbol object to clone.
4618      * @returns {Object} Returns the cloned symbol object.
4619      */
4620     function cloneSymbol(symbol) {
4621       return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4622     }
4623
4624     /**
4625      * Creates a clone of `typedArray`.
4626      *
4627      * @private
4628      * @param {Object} typedArray The typed array to clone.
4629      * @param {boolean} [isDeep] Specify a deep clone.
4630      * @returns {Object} Returns the cloned typed array.
4631      */
4632     function cloneTypedArray(typedArray, isDeep) {
4633       var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4634       return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4635     }
4636
4637     /**
4638      * Compares values to sort them in ascending order.
4639      *
4640      * @private
4641      * @param {*} value The value to compare.
4642      * @param {*} other The other value to compare.
4643      * @returns {number} Returns the sort order indicator for `value`.
4644      */
4645     function compareAscending(value, other) {
4646       if (value !== other) {
4647         var valIsDefined = value !== undefined,
4648             valIsNull = value === null,
4649             valIsReflexive = value === value,
4650             valIsSymbol = isSymbol(value);
4651
4652         var othIsDefined = other !== undefined,
4653             othIsNull = other === null,
4654             othIsReflexive = other === other,
4655             othIsSymbol = isSymbol(other);
4656
4657         if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4658             (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4659             (valIsNull && othIsDefined && othIsReflexive) ||
4660             (!valIsDefined && othIsReflexive) ||
4661             !valIsReflexive) {
4662           return 1;
4663         }
4664         if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4665             (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4666             (othIsNull && valIsDefined && valIsReflexive) ||
4667             (!othIsDefined && valIsReflexive) ||
4668             !othIsReflexive) {
4669           return -1;
4670         }
4671       }
4672       return 0;
4673     }
4674
4675     /**
4676      * Used by `_.orderBy` to compare multiple properties of a value to another
4677      * and stable sort them.
4678      *
4679      * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4680      * specify an order of "desc" for descending or "asc" for ascending sort order
4681      * of corresponding values.
4682      *
4683      * @private
4684      * @param {Object} object The object to compare.
4685      * @param {Object} other The other object to compare.
4686      * @param {boolean[]|string[]} orders The order to sort by for each property.
4687      * @returns {number} Returns the sort order indicator for `object`.
4688      */
4689     function compareMultiple(object, other, orders) {
4690       var index = -1,
4691           objCriteria = object.criteria,
4692           othCriteria = other.criteria,
4693           length = objCriteria.length,
4694           ordersLength = orders.length;
4695
4696       while (++index < length) {
4697         var result = compareAscending(objCriteria[index], othCriteria[index]);
4698         if (result) {
4699           if (index >= ordersLength) {
4700             return result;
4701           }
4702           var order = orders[index];
4703           return result * (order == 'desc' ? -1 : 1);
4704         }
4705       }
4706       // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4707       // that causes it, under certain circumstances, to provide the same value for
4708       // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4709       // for more details.
4710       //
4711       // This also ensures a stable sort in V8 and other engines.
4712       // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4713       return object.index - other.index;
4714     }
4715
4716     /**
4717      * Creates an array that is the composition of partially applied arguments,
4718      * placeholders, and provided arguments into a single array of arguments.
4719      *
4720      * @private
4721      * @param {Array} args The provided arguments.
4722      * @param {Array} partials The arguments to prepend to those provided.
4723      * @param {Array} holders The `partials` placeholder indexes.
4724      * @params {boolean} [isCurried] Specify composing for a curried function.
4725      * @returns {Array} Returns the new array of composed arguments.
4726      */
4727     function composeArgs(args, partials, holders, isCurried) {
4728       var argsIndex = -1,
4729           argsLength = args.length,
4730           holdersLength = holders.length,
4731           leftIndex = -1,
4732           leftLength = partials.length,
4733           rangeLength = nativeMax(argsLength - holdersLength, 0),
4734           result = Array(leftLength + rangeLength),
4735           isUncurried = !isCurried;
4736
4737       while (++leftIndex < leftLength) {
4738         result[leftIndex] = partials[leftIndex];
4739       }
4740       while (++argsIndex < holdersLength) {
4741         if (isUncurried || argsIndex < argsLength) {
4742           result[holders[argsIndex]] = args[argsIndex];
4743         }
4744       }
4745       while (rangeLength--) {
4746         result[leftIndex++] = args[argsIndex++];
4747       }
4748       return result;
4749     }
4750
4751     /**
4752      * This function is like `composeArgs` except that the arguments composition
4753      * is tailored for `_.partialRight`.
4754      *
4755      * @private
4756      * @param {Array} args The provided arguments.
4757      * @param {Array} partials The arguments to append 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.
4761      */
4762     function composeArgsRight(args, partials, holders, isCurried) {
4763       var argsIndex = -1,
4764           argsLength = args.length,
4765           holdersIndex = -1,
4766           holdersLength = holders.length,
4767           rightIndex = -1,
4768           rightLength = partials.length,
4769           rangeLength = nativeMax(argsLength - holdersLength, 0),
4770           result = Array(rangeLength + rightLength),
4771           isUncurried = !isCurried;
4772
4773       while (++argsIndex < rangeLength) {
4774         result[argsIndex] = args[argsIndex];
4775       }
4776       var offset = argsIndex;
4777       while (++rightIndex < rightLength) {
4778         result[offset + rightIndex] = partials[rightIndex];
4779       }
4780       while (++holdersIndex < holdersLength) {
4781         if (isUncurried || argsIndex < argsLength) {
4782           result[offset + holders[holdersIndex]] = args[argsIndex++];
4783         }
4784       }
4785       return result;
4786     }
4787
4788     /**
4789      * Copies the values of `source` to `array`.
4790      *
4791      * @private
4792      * @param {Array} source The array to copy values from.
4793      * @param {Array} [array=[]] The array to copy values to.
4794      * @returns {Array} Returns `array`.
4795      */
4796     function copyArray(source, array) {
4797       var index = -1,
4798           length = source.length;
4799
4800       array || (array = Array(length));
4801       while (++index < length) {
4802         array[index] = source[index];
4803       }
4804       return array;
4805     }
4806
4807     /**
4808      * Copies properties of `source` to `object`.
4809      *
4810      * @private
4811      * @param {Object} source The object to copy properties from.
4812      * @param {Array} props The property identifiers to copy.
4813      * @param {Object} [object={}] The object to copy properties to.
4814      * @param {Function} [customizer] The function to customize copied values.
4815      * @returns {Object} Returns `object`.
4816      */
4817     function copyObject(source, props, object, customizer) {
4818       var isNew = !object;
4819       object || (object = {});
4820
4821       var index = -1,
4822           length = props.length;
4823
4824       while (++index < length) {
4825         var key = props[index];
4826
4827         var newValue = customizer
4828           ? customizer(object[key], source[key], key, object, source)
4829           : undefined;
4830
4831         if (newValue === undefined) {
4832           newValue = source[key];
4833         }
4834         if (isNew) {
4835           baseAssignValue(object, key, newValue);
4836         } else {
4837           assignValue(object, key, newValue);
4838         }
4839       }
4840       return object;
4841     }
4842
4843     /**
4844      * Copies own symbols of `source` to `object`.
4845      *
4846      * @private
4847      * @param {Object} source The object to copy symbols from.
4848      * @param {Object} [object={}] The object to copy symbols to.
4849      * @returns {Object} Returns `object`.
4850      */
4851     function copySymbols(source, object) {
4852       return copyObject(source, getSymbols(source), object);
4853     }
4854
4855     /**
4856      * Copies own and inherited symbols of `source` to `object`.
4857      *
4858      * @private
4859      * @param {Object} source The object to copy symbols from.
4860      * @param {Object} [object={}] The object to copy symbols to.
4861      * @returns {Object} Returns `object`.
4862      */
4863     function copySymbolsIn(source, object) {
4864       return copyObject(source, getSymbolsIn(source), object);
4865     }
4866
4867     /**
4868      * Creates a function like `_.groupBy`.
4869      *
4870      * @private
4871      * @param {Function} setter The function to set accumulator values.
4872      * @param {Function} [initializer] The accumulator object initializer.
4873      * @returns {Function} Returns the new aggregator function.
4874      */
4875     function createAggregator(setter, initializer) {
4876       return function(collection, iteratee) {
4877         var func = isArray(collection) ? arrayAggregator : baseAggregator,
4878             accumulator = initializer ? initializer() : {};
4879
4880         return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4881       };
4882     }
4883
4884     /**
4885      * Creates a function like `_.assign`.
4886      *
4887      * @private
4888      * @param {Function} assigner The function to assign values.
4889      * @returns {Function} Returns the new assigner function.
4890      */
4891     function createAssigner(assigner) {
4892       return baseRest(function(object, sources) {
4893         var index = -1,
4894             length = sources.length,
4895             customizer = length > 1 ? sources[length - 1] : undefined,
4896             guard = length > 2 ? sources[2] : undefined;
4897
4898         customizer = (assigner.length > 3 && typeof customizer == 'function')
4899           ? (length--, customizer)
4900           : undefined;
4901
4902         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4903           customizer = length < 3 ? undefined : customizer;
4904           length = 1;
4905         }
4906         object = Object(object);
4907         while (++index < length) {
4908           var source = sources[index];
4909           if (source) {
4910             assigner(object, source, index, customizer);
4911           }
4912         }
4913         return object;
4914       });
4915     }
4916
4917     /**
4918      * Creates a `baseEach` or `baseEachRight` function.
4919      *
4920      * @private
4921      * @param {Function} eachFunc The function to iterate over a collection.
4922      * @param {boolean} [fromRight] Specify iterating from right to left.
4923      * @returns {Function} Returns the new base function.
4924      */
4925     function createBaseEach(eachFunc, fromRight) {
4926       return function(collection, iteratee) {
4927         if (collection == null) {
4928           return collection;
4929         }
4930         if (!isArrayLike(collection)) {
4931           return eachFunc(collection, iteratee);
4932         }
4933         var length = collection.length,
4934             index = fromRight ? length : -1,
4935             iterable = Object(collection);
4936
4937         while ((fromRight ? index-- : ++index < length)) {
4938           if (iteratee(iterable[index], index, iterable) === false) {
4939             break;
4940           }
4941         }
4942         return collection;
4943       };
4944     }
4945
4946     /**
4947      * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4948      *
4949      * @private
4950      * @param {boolean} [fromRight] Specify iterating from right to left.
4951      * @returns {Function} Returns the new base function.
4952      */
4953     function createBaseFor(fromRight) {
4954       return function(object, iteratee, keysFunc) {
4955         var index = -1,
4956             iterable = Object(object),
4957             props = keysFunc(object),
4958             length = props.length;
4959
4960         while (length--) {
4961           var key = props[fromRight ? length : ++index];
4962           if (iteratee(iterable[key], key, iterable) === false) {
4963             break;
4964           }
4965         }
4966         return object;
4967       };
4968     }
4969
4970     /**
4971      * Creates a function that wraps `func` to invoke it with the optional `this`
4972      * binding of `thisArg`.
4973      *
4974      * @private
4975      * @param {Function} func The function to wrap.
4976      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
4977      * @param {*} [thisArg] The `this` binding of `func`.
4978      * @returns {Function} Returns the new wrapped function.
4979      */
4980     function createBind(func, bitmask, thisArg) {
4981       var isBind = bitmask & WRAP_BIND_FLAG,
4982           Ctor = createCtor(func);
4983
4984       function wrapper() {
4985         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4986         return fn.apply(isBind ? thisArg : this, arguments);
4987       }
4988       return wrapper;
4989     }
4990
4991     /**
4992      * Creates a function like `_.lowerFirst`.
4993      *
4994      * @private
4995      * @param {string} methodName The name of the `String` case method to use.
4996      * @returns {Function} Returns the new case function.
4997      */
4998     function createCaseFirst(methodName) {
4999       return function(string) {
5000         string = toString(string);
5001
5002         var strSymbols = hasUnicode(string)
5003           ? stringToArray(string)
5004           : undefined;
5005
5006         var chr = strSymbols
5007           ? strSymbols[0]
5008           : string.charAt(0);
5009
5010         var trailing = strSymbols
5011           ? castSlice(strSymbols, 1).join('')
5012           : string.slice(1);
5013
5014         return chr[methodName]() + trailing;
5015       };
5016     }
5017
5018     /**
5019      * Creates a function like `_.camelCase`.
5020      *
5021      * @private
5022      * @param {Function} callback The function to combine each word.
5023      * @returns {Function} Returns the new compounder function.
5024      */
5025     function createCompounder(callback) {
5026       return function(string) {
5027         return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
5028       };
5029     }
5030
5031     /**
5032      * Creates a function that produces an instance of `Ctor` regardless of
5033      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5034      *
5035      * @private
5036      * @param {Function} Ctor The constructor to wrap.
5037      * @returns {Function} Returns the new wrapped function.
5038      */
5039     function createCtor(Ctor) {
5040       return function() {
5041         // Use a `switch` statement to work with class constructors. See
5042         // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5043         // for more details.
5044         var args = arguments;
5045         switch (args.length) {
5046           case 0: return new Ctor;
5047           case 1: return new Ctor(args[0]);
5048           case 2: return new Ctor(args[0], args[1]);
5049           case 3: return new Ctor(args[0], args[1], args[2]);
5050           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5051           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5052           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5053           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5054         }
5055         var thisBinding = baseCreate(Ctor.prototype),
5056             result = Ctor.apply(thisBinding, args);
5057
5058         // Mimic the constructor's `return` behavior.
5059         // See https://es5.github.io/#x13.2.2 for more details.
5060         return isObject(result) ? result : thisBinding;
5061       };
5062     }
5063
5064     /**
5065      * Creates a function that wraps `func` to enable currying.
5066      *
5067      * @private
5068      * @param {Function} func The function to wrap.
5069      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5070      * @param {number} arity The arity of `func`.
5071      * @returns {Function} Returns the new wrapped function.
5072      */
5073     function createCurry(func, bitmask, arity) {
5074       var Ctor = createCtor(func);
5075
5076       function wrapper() {
5077         var length = arguments.length,
5078             args = Array(length),
5079             index = length,
5080             placeholder = getHolder(wrapper);
5081
5082         while (index--) {
5083           args[index] = arguments[index];
5084         }
5085         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5086           ? []
5087           : replaceHolders(args, placeholder);
5088
5089         length -= holders.length;
5090         if (length < arity) {
5091           return createRecurry(
5092             func, bitmask, createHybrid, wrapper.placeholder, undefined,
5093             args, holders, undefined, undefined, arity - length);
5094         }
5095         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5096         return apply(fn, this, args);
5097       }
5098       return wrapper;
5099     }
5100
5101     /**
5102      * Creates a `_.find` or `_.findLast` function.
5103      *
5104      * @private
5105      * @param {Function} findIndexFunc The function to find the collection index.
5106      * @returns {Function} Returns the new find function.
5107      */
5108     function createFind(findIndexFunc) {
5109       return function(collection, predicate, fromIndex) {
5110         var iterable = Object(collection);
5111         if (!isArrayLike(collection)) {
5112           var iteratee = getIteratee(predicate, 3);
5113           collection = keys(collection);
5114           predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5115         }
5116         var index = findIndexFunc(collection, predicate, fromIndex);
5117         return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5118       };
5119     }
5120
5121     /**
5122      * Creates a `_.flow` or `_.flowRight` function.
5123      *
5124      * @private
5125      * @param {boolean} [fromRight] Specify iterating from right to left.
5126      * @returns {Function} Returns the new flow function.
5127      */
5128     function createFlow(fromRight) {
5129       return flatRest(function(funcs) {
5130         var length = funcs.length,
5131             index = length,
5132             prereq = LodashWrapper.prototype.thru;
5133
5134         if (fromRight) {
5135           funcs.reverse();
5136         }
5137         while (index--) {
5138           var func = funcs[index];
5139           if (typeof func != 'function') {
5140             throw new TypeError(FUNC_ERROR_TEXT);
5141           }
5142           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5143             var wrapper = new LodashWrapper([], true);
5144           }
5145         }
5146         index = wrapper ? index : length;
5147         while (++index < length) {
5148           func = funcs[index];
5149
5150           var funcName = getFuncName(func),
5151               data = funcName == 'wrapper' ? getData(func) : undefined;
5152
5153           if (data && isLaziable(data[0]) &&
5154                 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5155                 !data[4].length && data[9] == 1
5156               ) {
5157             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5158           } else {
5159             wrapper = (func.length == 1 && isLaziable(func))
5160               ? wrapper[funcName]()
5161               : wrapper.thru(func);
5162           }
5163         }
5164         return function() {
5165           var args = arguments,
5166               value = args[0];
5167
5168           if (wrapper && args.length == 1 && isArray(value)) {
5169             return wrapper.plant(value).value();
5170           }
5171           var index = 0,
5172               result = length ? funcs[index].apply(this, args) : value;
5173
5174           while (++index < length) {
5175             result = funcs[index].call(this, result);
5176           }
5177           return result;
5178         };
5179       });
5180     }
5181
5182     /**
5183      * Creates a function that wraps `func` to invoke it with optional `this`
5184      * binding of `thisArg`, partial application, and currying.
5185      *
5186      * @private
5187      * @param {Function|string} func The function or method name to wrap.
5188      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5189      * @param {*} [thisArg] The `this` binding of `func`.
5190      * @param {Array} [partials] The arguments to prepend to those provided to
5191      *  the new function.
5192      * @param {Array} [holders] The `partials` placeholder indexes.
5193      * @param {Array} [partialsRight] The arguments to append to those provided
5194      *  to the new function.
5195      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5196      * @param {Array} [argPos] The argument positions of the new function.
5197      * @param {number} [ary] The arity cap of `func`.
5198      * @param {number} [arity] The arity of `func`.
5199      * @returns {Function} Returns the new wrapped function.
5200      */
5201     function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5202       var isAry = bitmask & WRAP_ARY_FLAG,
5203           isBind = bitmask & WRAP_BIND_FLAG,
5204           isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5205           isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5206           isFlip = bitmask & WRAP_FLIP_FLAG,
5207           Ctor = isBindKey ? undefined : createCtor(func);
5208
5209       function wrapper() {
5210         var length = arguments.length,
5211             args = Array(length),
5212             index = length;
5213
5214         while (index--) {
5215           args[index] = arguments[index];
5216         }
5217         if (isCurried) {
5218           var placeholder = getHolder(wrapper),
5219               holdersCount = countHolders(args, placeholder);
5220         }
5221         if (partials) {
5222           args = composeArgs(args, partials, holders, isCurried);
5223         }
5224         if (partialsRight) {
5225           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5226         }
5227         length -= holdersCount;
5228         if (isCurried && length < arity) {
5229           var newHolders = replaceHolders(args, placeholder);
5230           return createRecurry(
5231             func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5232             args, newHolders, argPos, ary, arity - length
5233           );
5234         }
5235         var thisBinding = isBind ? thisArg : this,
5236             fn = isBindKey ? thisBinding[func] : func;
5237
5238         length = args.length;
5239         if (argPos) {
5240           args = reorder(args, argPos);
5241         } else if (isFlip && length > 1) {
5242           args.reverse();
5243         }
5244         if (isAry && ary < length) {
5245           args.length = ary;
5246         }
5247         if (this && this !== root && this instanceof wrapper) {
5248           fn = Ctor || createCtor(fn);
5249         }
5250         return fn.apply(thisBinding, args);
5251       }
5252       return wrapper;
5253     }
5254
5255     /**
5256      * Creates a function like `_.invertBy`.
5257      *
5258      * @private
5259      * @param {Function} setter The function to set accumulator values.
5260      * @param {Function} toIteratee The function to resolve iteratees.
5261      * @returns {Function} Returns the new inverter function.
5262      */
5263     function createInverter(setter, toIteratee) {
5264       return function(object, iteratee) {
5265         return baseInverter(object, setter, toIteratee(iteratee), {});
5266       };
5267     }
5268
5269     /**
5270      * Creates a function that performs a mathematical operation on two values.
5271      *
5272      * @private
5273      * @param {Function} operator The function to perform the operation.
5274      * @param {number} [defaultValue] The value used for `undefined` arguments.
5275      * @returns {Function} Returns the new mathematical operation function.
5276      */
5277     function createMathOperation(operator, defaultValue) {
5278       return function(value, other) {
5279         var result;
5280         if (value === undefined && other === undefined) {
5281           return defaultValue;
5282         }
5283         if (value !== undefined) {
5284           result = value;
5285         }
5286         if (other !== undefined) {
5287           if (result === undefined) {
5288             return other;
5289           }
5290           if (typeof value == 'string' || typeof other == 'string') {
5291             value = baseToString(value);
5292             other = baseToString(other);
5293           } else {
5294             value = baseToNumber(value);
5295             other = baseToNumber(other);
5296           }
5297           result = operator(value, other);
5298         }
5299         return result;
5300       };
5301     }
5302
5303     /**
5304      * Creates a function like `_.over`.
5305      *
5306      * @private
5307      * @param {Function} arrayFunc The function to iterate over iteratees.
5308      * @returns {Function} Returns the new over function.
5309      */
5310     function createOver(arrayFunc) {
5311       return flatRest(function(iteratees) {
5312         iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5313         return baseRest(function(args) {
5314           var thisArg = this;
5315           return arrayFunc(iteratees, function(iteratee) {
5316             return apply(iteratee, thisArg, args);
5317           });
5318         });
5319       });
5320     }
5321
5322     /**
5323      * Creates the padding for `string` based on `length`. The `chars` string
5324      * is truncated if the number of characters exceeds `length`.
5325      *
5326      * @private
5327      * @param {number} length The padding length.
5328      * @param {string} [chars=' '] The string used as padding.
5329      * @returns {string} Returns the padding for `string`.
5330      */
5331     function createPadding(length, chars) {
5332       chars = chars === undefined ? ' ' : baseToString(chars);
5333
5334       var charsLength = chars.length;
5335       if (charsLength < 2) {
5336         return charsLength ? baseRepeat(chars, length) : chars;
5337       }
5338       var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5339       return hasUnicode(chars)
5340         ? castSlice(stringToArray(result), 0, length).join('')
5341         : result.slice(0, length);
5342     }
5343
5344     /**
5345      * Creates a function that wraps `func` to invoke it with the `this` binding
5346      * of `thisArg` and `partials` prepended to the arguments it receives.
5347      *
5348      * @private
5349      * @param {Function} func The function to wrap.
5350      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5351      * @param {*} thisArg The `this` binding of `func`.
5352      * @param {Array} partials The arguments to prepend to those provided to
5353      *  the new function.
5354      * @returns {Function} Returns the new wrapped function.
5355      */
5356     function createPartial(func, bitmask, thisArg, partials) {
5357       var isBind = bitmask & WRAP_BIND_FLAG,
5358           Ctor = createCtor(func);
5359
5360       function wrapper() {
5361         var argsIndex = -1,
5362             argsLength = arguments.length,
5363             leftIndex = -1,
5364             leftLength = partials.length,
5365             args = Array(leftLength + argsLength),
5366             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5367
5368         while (++leftIndex < leftLength) {
5369           args[leftIndex] = partials[leftIndex];
5370         }
5371         while (argsLength--) {
5372           args[leftIndex++] = arguments[++argsIndex];
5373         }
5374         return apply(fn, isBind ? thisArg : this, args);
5375       }
5376       return wrapper;
5377     }
5378
5379     /**
5380      * Creates a `_.range` or `_.rangeRight` function.
5381      *
5382      * @private
5383      * @param {boolean} [fromRight] Specify iterating from right to left.
5384      * @returns {Function} Returns the new range function.
5385      */
5386     function createRange(fromRight) {
5387       return function(start, end, step) {
5388         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5389           end = step = undefined;
5390         }
5391         // Ensure the sign of `-0` is preserved.
5392         start = toFinite(start);
5393         if (end === undefined) {
5394           end = start;
5395           start = 0;
5396         } else {
5397           end = toFinite(end);
5398         }
5399         step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5400         return baseRange(start, end, step, fromRight);
5401       };
5402     }
5403
5404     /**
5405      * Creates a function that performs a relational operation on two values.
5406      *
5407      * @private
5408      * @param {Function} operator The function to perform the operation.
5409      * @returns {Function} Returns the new relational operation function.
5410      */
5411     function createRelationalOperation(operator) {
5412       return function(value, other) {
5413         if (!(typeof value == 'string' && typeof other == 'string')) {
5414           value = toNumber(value);
5415           other = toNumber(other);
5416         }
5417         return operator(value, other);
5418       };
5419     }
5420
5421     /**
5422      * Creates a function that wraps `func` to continue currying.
5423      *
5424      * @private
5425      * @param {Function} func The function to wrap.
5426      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5427      * @param {Function} wrapFunc The function to create the `func` wrapper.
5428      * @param {*} placeholder The placeholder value.
5429      * @param {*} [thisArg] The `this` binding of `func`.
5430      * @param {Array} [partials] The arguments to prepend to those provided to
5431      *  the new function.
5432      * @param {Array} [holders] The `partials` placeholder indexes.
5433      * @param {Array} [argPos] The argument positions of the new function.
5434      * @param {number} [ary] The arity cap of `func`.
5435      * @param {number} [arity] The arity of `func`.
5436      * @returns {Function} Returns the new wrapped function.
5437      */
5438     function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5439       var isCurry = bitmask & WRAP_CURRY_FLAG,
5440           newHolders = isCurry ? holders : undefined,
5441           newHoldersRight = isCurry ? undefined : holders,
5442           newPartials = isCurry ? partials : undefined,
5443           newPartialsRight = isCurry ? undefined : partials;
5444
5445       bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5446       bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5447
5448       if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5449         bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5450       }
5451       var newData = [
5452         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5453         newHoldersRight, argPos, ary, arity
5454       ];
5455
5456       var result = wrapFunc.apply(undefined, newData);
5457       if (isLaziable(func)) {
5458         setData(result, newData);
5459       }
5460       result.placeholder = placeholder;
5461       return setWrapToString(result, func, bitmask);
5462     }
5463
5464     /**
5465      * Creates a function like `_.round`.
5466      *
5467      * @private
5468      * @param {string} methodName The name of the `Math` method to use when rounding.
5469      * @returns {Function} Returns the new round function.
5470      */
5471     function createRound(methodName) {
5472       var func = Math[methodName];
5473       return function(number, precision) {
5474         number = toNumber(number);
5475         precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
5476         if (precision) {
5477           // Shift with exponential notation to avoid floating-point issues.
5478           // See [MDN](https://mdn.io/round#Examples) for more details.
5479           var pair = (toString(number) + 'e').split('e'),
5480               value = func(pair[0] + 'e' + (+pair[1] + precision));
5481
5482           pair = (toString(value) + 'e').split('e');
5483           return +(pair[0] + 'e' + (+pair[1] - precision));
5484         }
5485         return func(number);
5486       };
5487     }
5488
5489     /**
5490      * Creates a set object of `values`.
5491      *
5492      * @private
5493      * @param {Array} values The values to add to the set.
5494      * @returns {Object} Returns the new set.
5495      */
5496     var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5497       return new Set(values);
5498     };
5499
5500     /**
5501      * Creates a `_.toPairs` or `_.toPairsIn` function.
5502      *
5503      * @private
5504      * @param {Function} keysFunc The function to get the keys of a given object.
5505      * @returns {Function} Returns the new pairs function.
5506      */
5507     function createToPairs(keysFunc) {
5508       return function(object) {
5509         var tag = getTag(object);
5510         if (tag == mapTag) {
5511           return mapToArray(object);
5512         }
5513         if (tag == setTag) {
5514           return setToPairs(object);
5515         }
5516         return baseToPairs(object, keysFunc(object));
5517       };
5518     }
5519
5520     /**
5521      * Creates a function that either curries or invokes `func` with optional
5522      * `this` binding and partially applied arguments.
5523      *
5524      * @private
5525      * @param {Function|string} func The function or method name to wrap.
5526      * @param {number} bitmask The bitmask flags.
5527      *    1 - `_.bind`
5528      *    2 - `_.bindKey`
5529      *    4 - `_.curry` or `_.curryRight` of a bound function
5530      *    8 - `_.curry`
5531      *   16 - `_.curryRight`
5532      *   32 - `_.partial`
5533      *   64 - `_.partialRight`
5534      *  128 - `_.rearg`
5535      *  256 - `_.ary`
5536      *  512 - `_.flip`
5537      * @param {*} [thisArg] The `this` binding of `func`.
5538      * @param {Array} [partials] The arguments to be partially applied.
5539      * @param {Array} [holders] The `partials` placeholder indexes.
5540      * @param {Array} [argPos] The argument positions of the new function.
5541      * @param {number} [ary] The arity cap of `func`.
5542      * @param {number} [arity] The arity of `func`.
5543      * @returns {Function} Returns the new wrapped function.
5544      */
5545     function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5546       var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5547       if (!isBindKey && typeof func != 'function') {
5548         throw new TypeError(FUNC_ERROR_TEXT);
5549       }
5550       var length = partials ? partials.length : 0;
5551       if (!length) {
5552         bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5553         partials = holders = undefined;
5554       }
5555       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5556       arity = arity === undefined ? arity : toInteger(arity);
5557       length -= holders ? holders.length : 0;
5558
5559       if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5560         var partialsRight = partials,
5561             holdersRight = holders;
5562
5563         partials = holders = undefined;
5564       }
5565       var data = isBindKey ? undefined : getData(func);
5566
5567       var newData = [
5568         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5569         argPos, ary, arity
5570       ];
5571
5572       if (data) {
5573         mergeData(newData, data);
5574       }
5575       func = newData[0];
5576       bitmask = newData[1];
5577       thisArg = newData[2];
5578       partials = newData[3];
5579       holders = newData[4];
5580       arity = newData[9] = newData[9] === undefined
5581         ? (isBindKey ? 0 : func.length)
5582         : nativeMax(newData[9] - length, 0);
5583
5584       if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5585         bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5586       }
5587       if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5588         var result = createBind(func, bitmask, thisArg);
5589       } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5590         result = createCurry(func, bitmask, arity);
5591       } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5592         result = createPartial(func, bitmask, thisArg, partials);
5593       } else {
5594         result = createHybrid.apply(undefined, newData);
5595       }
5596       var setter = data ? baseSetData : setData;
5597       return setWrapToString(setter(result, newData), func, bitmask);
5598     }
5599
5600     /**
5601      * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
5602      * of source objects to the destination object for all destination properties
5603      * that resolve to `undefined`.
5604      *
5605      * @private
5606      * @param {*} objValue The destination value.
5607      * @param {*} srcValue The source value.
5608      * @param {string} key The key of the property to assign.
5609      * @param {Object} object The parent object of `objValue`.
5610      * @returns {*} Returns the value to assign.
5611      */
5612     function customDefaultsAssignIn(objValue, srcValue, key, object) {
5613       if (objValue === undefined ||
5614           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
5615         return srcValue;
5616       }
5617       return objValue;
5618     }
5619
5620     /**
5621      * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
5622      * objects into destination objects that are passed thru.
5623      *
5624      * @private
5625      * @param {*} objValue The destination value.
5626      * @param {*} srcValue The source value.
5627      * @param {string} key The key of the property to merge.
5628      * @param {Object} object The parent object of `objValue`.
5629      * @param {Object} source The parent object of `srcValue`.
5630      * @param {Object} [stack] Tracks traversed source values and their merged
5631      *  counterparts.
5632      * @returns {*} Returns the value to assign.
5633      */
5634     function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
5635       if (isObject(objValue) && isObject(srcValue)) {
5636         // Recursively merge objects and arrays (susceptible to call stack limits).
5637         stack.set(srcValue, objValue);
5638         baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
5639         stack['delete'](srcValue);
5640       }
5641       return objValue;
5642     }
5643
5644     /**
5645      * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
5646      * objects.
5647      *
5648      * @private
5649      * @param {*} value The value to inspect.
5650      * @param {string} key The key of the property to inspect.
5651      * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
5652      */
5653     function customOmitClone(value) {
5654       return isPlainObject(value) ? undefined : value;
5655     }
5656
5657     /**
5658      * A specialized version of `baseIsEqualDeep` for arrays with support for
5659      * partial deep comparisons.
5660      *
5661      * @private
5662      * @param {Array} array The array to compare.
5663      * @param {Array} other The other array to compare.
5664      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5665      * @param {Function} customizer The function to customize comparisons.
5666      * @param {Function} equalFunc The function to determine equivalents of values.
5667      * @param {Object} stack Tracks traversed `array` and `other` objects.
5668      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5669      */
5670     function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5671       var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5672           arrLength = array.length,
5673           othLength = other.length;
5674
5675       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5676         return false;
5677       }
5678       // Assume cyclic values are equal.
5679       var stacked = stack.get(array);
5680       if (stacked && stack.get(other)) {
5681         return stacked == other;
5682       }
5683       var index = -1,
5684           result = true,
5685           seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5686
5687       stack.set(array, other);
5688       stack.set(other, array);
5689
5690       // Ignore non-index properties.
5691       while (++index < arrLength) {
5692         var arrValue = array[index],
5693             othValue = other[index];
5694
5695         if (customizer) {
5696           var compared = isPartial
5697             ? customizer(othValue, arrValue, index, other, array, stack)
5698             : customizer(arrValue, othValue, index, array, other, stack);
5699         }
5700         if (compared !== undefined) {
5701           if (compared) {
5702             continue;
5703           }
5704           result = false;
5705           break;
5706         }
5707         // Recursively compare arrays (susceptible to call stack limits).
5708         if (seen) {
5709           if (!arraySome(other, function(othValue, othIndex) {
5710                 if (!cacheHas(seen, othIndex) &&
5711                     (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5712                   return seen.push(othIndex);
5713                 }
5714               })) {
5715             result = false;
5716             break;
5717           }
5718         } else if (!(
5719               arrValue === othValue ||
5720                 equalFunc(arrValue, othValue, bitmask, customizer, stack)
5721             )) {
5722           result = false;
5723           break;
5724         }
5725       }
5726       stack['delete'](array);
5727       stack['delete'](other);
5728       return result;
5729     }
5730
5731     /**
5732      * A specialized version of `baseIsEqualDeep` for comparing objects of
5733      * the same `toStringTag`.
5734      *
5735      * **Note:** This function only supports comparing values with tags of
5736      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5737      *
5738      * @private
5739      * @param {Object} object The object to compare.
5740      * @param {Object} other The other object to compare.
5741      * @param {string} tag The `toStringTag` of the objects to compare.
5742      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5743      * @param {Function} customizer The function to customize comparisons.
5744      * @param {Function} equalFunc The function to determine equivalents of values.
5745      * @param {Object} stack Tracks traversed `object` and `other` objects.
5746      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5747      */
5748     function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5749       switch (tag) {
5750         case dataViewTag:
5751           if ((object.byteLength != other.byteLength) ||
5752               (object.byteOffset != other.byteOffset)) {
5753             return false;
5754           }
5755           object = object.buffer;
5756           other = other.buffer;
5757
5758         case arrayBufferTag:
5759           if ((object.byteLength != other.byteLength) ||
5760               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5761             return false;
5762           }
5763           return true;
5764
5765         case boolTag:
5766         case dateTag:
5767         case numberTag:
5768           // Coerce booleans to `1` or `0` and dates to milliseconds.
5769           // Invalid dates are coerced to `NaN`.
5770           return eq(+object, +other);
5771
5772         case errorTag:
5773           return object.name == other.name && object.message == other.message;
5774
5775         case regexpTag:
5776         case stringTag:
5777           // Coerce regexes to strings and treat strings, primitives and objects,
5778           // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5779           // for more details.
5780           return object == (other + '');
5781
5782         case mapTag:
5783           var convert = mapToArray;
5784
5785         case setTag:
5786           var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5787           convert || (convert = setToArray);
5788
5789           if (object.size != other.size && !isPartial) {
5790             return false;
5791           }
5792           // Assume cyclic values are equal.
5793           var stacked = stack.get(object);
5794           if (stacked) {
5795             return stacked == other;
5796           }
5797           bitmask |= COMPARE_UNORDERED_FLAG;
5798
5799           // Recursively compare objects (susceptible to call stack limits).
5800           stack.set(object, other);
5801           var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5802           stack['delete'](object);
5803           return result;
5804
5805         case symbolTag:
5806           if (symbolValueOf) {
5807             return symbolValueOf.call(object) == symbolValueOf.call(other);
5808           }
5809       }
5810       return false;
5811     }
5812
5813     /**
5814      * A specialized version of `baseIsEqualDeep` for objects with support for
5815      * partial deep comparisons.
5816      *
5817      * @private
5818      * @param {Object} object The object to compare.
5819      * @param {Object} other The other object to compare.
5820      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5821      * @param {Function} customizer The function to customize comparisons.
5822      * @param {Function} equalFunc The function to determine equivalents of values.
5823      * @param {Object} stack Tracks traversed `object` and `other` objects.
5824      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5825      */
5826     function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5827       var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5828           objProps = getAllKeys(object),
5829           objLength = objProps.length,
5830           othProps = getAllKeys(other),
5831           othLength = othProps.length;
5832
5833       if (objLength != othLength && !isPartial) {
5834         return false;
5835       }
5836       var index = objLength;
5837       while (index--) {
5838         var key = objProps[index];
5839         if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5840           return false;
5841         }
5842       }
5843       // Assume cyclic values are equal.
5844       var stacked = stack.get(object);
5845       if (stacked && stack.get(other)) {
5846         return stacked == other;
5847       }
5848       var result = true;
5849       stack.set(object, other);
5850       stack.set(other, object);
5851
5852       var skipCtor = isPartial;
5853       while (++index < objLength) {
5854         key = objProps[index];
5855         var objValue = object[key],
5856             othValue = other[key];
5857
5858         if (customizer) {
5859           var compared = isPartial
5860             ? customizer(othValue, objValue, key, other, object, stack)
5861             : customizer(objValue, othValue, key, object, other, stack);
5862         }
5863         // Recursively compare objects (susceptible to call stack limits).
5864         if (!(compared === undefined
5865               ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5866               : compared
5867             )) {
5868           result = false;
5869           break;
5870         }
5871         skipCtor || (skipCtor = key == 'constructor');
5872       }
5873       if (result && !skipCtor) {
5874         var objCtor = object.constructor,
5875             othCtor = other.constructor;
5876
5877         // Non `Object` object instances with different constructors are not equal.
5878         if (objCtor != othCtor &&
5879             ('constructor' in object && 'constructor' in other) &&
5880             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5881               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5882           result = false;
5883         }
5884       }
5885       stack['delete'](object);
5886       stack['delete'](other);
5887       return result;
5888     }
5889
5890     /**
5891      * A specialized version of `baseRest` which flattens the rest array.
5892      *
5893      * @private
5894      * @param {Function} func The function to apply a rest parameter to.
5895      * @returns {Function} Returns the new function.
5896      */
5897     function flatRest(func) {
5898       return setToString(overRest(func, undefined, flatten), func + '');
5899     }
5900
5901     /**
5902      * Creates an array of own enumerable property names and symbols of `object`.
5903      *
5904      * @private
5905      * @param {Object} object The object to query.
5906      * @returns {Array} Returns the array of property names and symbols.
5907      */
5908     function getAllKeys(object) {
5909       return baseGetAllKeys(object, keys, getSymbols);
5910     }
5911
5912     /**
5913      * Creates an array of own and inherited enumerable property names and
5914      * symbols of `object`.
5915      *
5916      * @private
5917      * @param {Object} object The object to query.
5918      * @returns {Array} Returns the array of property names and symbols.
5919      */
5920     function getAllKeysIn(object) {
5921       return baseGetAllKeys(object, keysIn, getSymbolsIn);
5922     }
5923
5924     /**
5925      * Gets metadata for `func`.
5926      *
5927      * @private
5928      * @param {Function} func The function to query.
5929      * @returns {*} Returns the metadata for `func`.
5930      */
5931     var getData = !metaMap ? noop : function(func) {
5932       return metaMap.get(func);
5933     };
5934
5935     /**
5936      * Gets the name of `func`.
5937      *
5938      * @private
5939      * @param {Function} func The function to query.
5940      * @returns {string} Returns the function name.
5941      */
5942     function getFuncName(func) {
5943       var result = (func.name + ''),
5944           array = realNames[result],
5945           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5946
5947       while (length--) {
5948         var data = array[length],
5949             otherFunc = data.func;
5950         if (otherFunc == null || otherFunc == func) {
5951           return data.name;
5952         }
5953       }
5954       return result;
5955     }
5956
5957     /**
5958      * Gets the argument placeholder value for `func`.
5959      *
5960      * @private
5961      * @param {Function} func The function to inspect.
5962      * @returns {*} Returns the placeholder value.
5963      */
5964     function getHolder(func) {
5965       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5966       return object.placeholder;
5967     }
5968
5969     /**
5970      * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5971      * this function returns the custom method, otherwise it returns `baseIteratee`.
5972      * If arguments are provided, the chosen function is invoked with them and
5973      * its result is returned.
5974      *
5975      * @private
5976      * @param {*} [value] The value to convert to an iteratee.
5977      * @param {number} [arity] The arity of the created iteratee.
5978      * @returns {Function} Returns the chosen function or its result.
5979      */
5980     function getIteratee() {
5981       var result = lodash.iteratee || iteratee;
5982       result = result === iteratee ? baseIteratee : result;
5983       return arguments.length ? result(arguments[0], arguments[1]) : result;
5984     }
5985
5986     /**
5987      * Gets the data for `map`.
5988      *
5989      * @private
5990      * @param {Object} map The map to query.
5991      * @param {string} key The reference key.
5992      * @returns {*} Returns the map data.
5993      */
5994     function getMapData(map, key) {
5995       var data = map.__data__;
5996       return isKeyable(key)
5997         ? data[typeof key == 'string' ? 'string' : 'hash']
5998         : data.map;
5999     }
6000
6001     /**
6002      * Gets the property names, values, and compare flags of `object`.
6003      *
6004      * @private
6005      * @param {Object} object The object to query.
6006      * @returns {Array} Returns the match data of `object`.
6007      */
6008     function getMatchData(object) {
6009       var result = keys(object),
6010           length = result.length;
6011
6012       while (length--) {
6013         var key = result[length],
6014             value = object[key];
6015
6016         result[length] = [key, value, isStrictComparable(value)];
6017       }
6018       return result;
6019     }
6020
6021     /**
6022      * Gets the native function at `key` of `object`.
6023      *
6024      * @private
6025      * @param {Object} object The object to query.
6026      * @param {string} key The key of the method to get.
6027      * @returns {*} Returns the function if it's native, else `undefined`.
6028      */
6029     function getNative(object, key) {
6030       var value = getValue(object, key);
6031       return baseIsNative(value) ? value : undefined;
6032     }
6033
6034     /**
6035      * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6036      *
6037      * @private
6038      * @param {*} value The value to query.
6039      * @returns {string} Returns the raw `toStringTag`.
6040      */
6041     function getRawTag(value) {
6042       var isOwn = hasOwnProperty.call(value, symToStringTag),
6043           tag = value[symToStringTag];
6044
6045       try {
6046         value[symToStringTag] = undefined;
6047         var unmasked = true;
6048       } catch (e) {}
6049
6050       var result = nativeObjectToString.call(value);
6051       if (unmasked) {
6052         if (isOwn) {
6053           value[symToStringTag] = tag;
6054         } else {
6055           delete value[symToStringTag];
6056         }
6057       }
6058       return result;
6059     }
6060
6061     /**
6062      * Creates an array of the own enumerable symbols of `object`.
6063      *
6064      * @private
6065      * @param {Object} object The object to query.
6066      * @returns {Array} Returns the array of symbols.
6067      */
6068     var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
6069       if (object == null) {
6070         return [];
6071       }
6072       object = Object(object);
6073       return arrayFilter(nativeGetSymbols(object), function(symbol) {
6074         return propertyIsEnumerable.call(object, symbol);
6075       });
6076     };
6077
6078     /**
6079      * Creates an array of the own and inherited enumerable symbols of `object`.
6080      *
6081      * @private
6082      * @param {Object} object The object to query.
6083      * @returns {Array} Returns the array of symbols.
6084      */
6085     var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6086       var result = [];
6087       while (object) {
6088         arrayPush(result, getSymbols(object));
6089         object = getPrototype(object);
6090       }
6091       return result;
6092     };
6093
6094     /**
6095      * Gets the `toStringTag` of `value`.
6096      *
6097      * @private
6098      * @param {*} value The value to query.
6099      * @returns {string} Returns the `toStringTag`.
6100      */
6101     var getTag = baseGetTag;
6102
6103     // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6104     if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6105         (Map && getTag(new Map) != mapTag) ||
6106         (Promise && getTag(Promise.resolve()) != promiseTag) ||
6107         (Set && getTag(new Set) != setTag) ||
6108         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6109       getTag = function(value) {
6110         var result = baseGetTag(value),
6111             Ctor = result == objectTag ? value.constructor : undefined,
6112             ctorString = Ctor ? toSource(Ctor) : '';
6113
6114         if (ctorString) {
6115           switch (ctorString) {
6116             case dataViewCtorString: return dataViewTag;
6117             case mapCtorString: return mapTag;
6118             case promiseCtorString: return promiseTag;
6119             case setCtorString: return setTag;
6120             case weakMapCtorString: return weakMapTag;
6121           }
6122         }
6123         return result;
6124       };
6125     }
6126
6127     /**
6128      * Gets the view, applying any `transforms` to the `start` and `end` positions.
6129      *
6130      * @private
6131      * @param {number} start The start of the view.
6132      * @param {number} end The end of the view.
6133      * @param {Array} transforms The transformations to apply to the view.
6134      * @returns {Object} Returns an object containing the `start` and `end`
6135      *  positions of the view.
6136      */
6137     function getView(start, end, transforms) {
6138       var index = -1,
6139           length = transforms.length;
6140
6141       while (++index < length) {
6142         var data = transforms[index],
6143             size = data.size;
6144
6145         switch (data.type) {
6146           case 'drop':      start += size; break;
6147           case 'dropRight': end -= size; break;
6148           case 'take':      end = nativeMin(end, start + size); break;
6149           case 'takeRight': start = nativeMax(start, end - size); break;
6150         }
6151       }
6152       return { 'start': start, 'end': end };
6153     }
6154
6155     /**
6156      * Extracts wrapper details from the `source` body comment.
6157      *
6158      * @private
6159      * @param {string} source The source to inspect.
6160      * @returns {Array} Returns the wrapper details.
6161      */
6162     function getWrapDetails(source) {
6163       var match = source.match(reWrapDetails);
6164       return match ? match[1].split(reSplitDetails) : [];
6165     }
6166
6167     /**
6168      * Checks if `path` exists on `object`.
6169      *
6170      * @private
6171      * @param {Object} object The object to query.
6172      * @param {Array|string} path The path to check.
6173      * @param {Function} hasFunc The function to check properties.
6174      * @returns {boolean} Returns `true` if `path` exists, else `false`.
6175      */
6176     function hasPath(object, path, hasFunc) {
6177       path = castPath(path, object);
6178
6179       var index = -1,
6180           length = path.length,
6181           result = false;
6182
6183       while (++index < length) {
6184         var key = toKey(path[index]);
6185         if (!(result = object != null && hasFunc(object, key))) {
6186           break;
6187         }
6188         object = object[key];
6189       }
6190       if (result || ++index != length) {
6191         return result;
6192       }
6193       length = object == null ? 0 : object.length;
6194       return !!length && isLength(length) && isIndex(key, length) &&
6195         (isArray(object) || isArguments(object));
6196     }
6197
6198     /**
6199      * Initializes an array clone.
6200      *
6201      * @private
6202      * @param {Array} array The array to clone.
6203      * @returns {Array} Returns the initialized clone.
6204      */
6205     function initCloneArray(array) {
6206       var length = array.length,
6207           result = array.constructor(length);
6208
6209       // Add properties assigned by `RegExp#exec`.
6210       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6211         result.index = array.index;
6212         result.input = array.input;
6213       }
6214       return result;
6215     }
6216
6217     /**
6218      * Initializes an object clone.
6219      *
6220      * @private
6221      * @param {Object} object The object to clone.
6222      * @returns {Object} Returns the initialized clone.
6223      */
6224     function initCloneObject(object) {
6225       return (typeof object.constructor == 'function' && !isPrototype(object))
6226         ? baseCreate(getPrototype(object))
6227         : {};
6228     }
6229
6230     /**
6231      * Initializes an object clone based on its `toStringTag`.
6232      *
6233      * **Note:** This function only supports cloning values with tags of
6234      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6235      *
6236      * @private
6237      * @param {Object} object The object to clone.
6238      * @param {string} tag The `toStringTag` of the object to clone.
6239      * @param {Function} cloneFunc The function to clone values.
6240      * @param {boolean} [isDeep] Specify a deep clone.
6241      * @returns {Object} Returns the initialized clone.
6242      */
6243     function initCloneByTag(object, tag, cloneFunc, isDeep) {
6244       var Ctor = object.constructor;
6245       switch (tag) {
6246         case arrayBufferTag:
6247           return cloneArrayBuffer(object);
6248
6249         case boolTag:
6250         case dateTag:
6251           return new Ctor(+object);
6252
6253         case dataViewTag:
6254           return cloneDataView(object, isDeep);
6255
6256         case float32Tag: case float64Tag:
6257         case int8Tag: case int16Tag: case int32Tag:
6258         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6259           return cloneTypedArray(object, isDeep);
6260
6261         case mapTag:
6262           return cloneMap(object, isDeep, cloneFunc);
6263
6264         case numberTag:
6265         case stringTag:
6266           return new Ctor(object);
6267
6268         case regexpTag:
6269           return cloneRegExp(object);
6270
6271         case setTag:
6272           return cloneSet(object, isDeep, cloneFunc);
6273
6274         case symbolTag:
6275           return cloneSymbol(object);
6276       }
6277     }
6278
6279     /**
6280      * Inserts wrapper `details` in a comment at the top of the `source` body.
6281      *
6282      * @private
6283      * @param {string} source The source to modify.
6284      * @returns {Array} details The details to insert.
6285      * @returns {string} Returns the modified source.
6286      */
6287     function insertWrapDetails(source, details) {
6288       var length = details.length;
6289       if (!length) {
6290         return source;
6291       }
6292       var lastIndex = length - 1;
6293       details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6294       details = details.join(length > 2 ? ', ' : ' ');
6295       return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6296     }
6297
6298     /**
6299      * Checks if `value` is a flattenable `arguments` object or array.
6300      *
6301      * @private
6302      * @param {*} value The value to check.
6303      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6304      */
6305     function isFlattenable(value) {
6306       return isArray(value) || isArguments(value) ||
6307         !!(spreadableSymbol && value && value[spreadableSymbol]);
6308     }
6309
6310     /**
6311      * Checks if `value` is a valid array-like index.
6312      *
6313      * @private
6314      * @param {*} value The value to check.
6315      * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6316      * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6317      */
6318     function isIndex(value, length) {
6319       length = length == null ? MAX_SAFE_INTEGER : length;
6320       return !!length &&
6321         (typeof value == 'number' || reIsUint.test(value)) &&
6322         (value > -1 && value % 1 == 0 && value < length);
6323     }
6324
6325     /**
6326      * Checks if the given arguments are from an iteratee call.
6327      *
6328      * @private
6329      * @param {*} value The potential iteratee value argument.
6330      * @param {*} index The potential iteratee index or key argument.
6331      * @param {*} object The potential iteratee object argument.
6332      * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6333      *  else `false`.
6334      */
6335     function isIterateeCall(value, index, object) {
6336       if (!isObject(object)) {
6337         return false;
6338       }
6339       var type = typeof index;
6340       if (type == 'number'
6341             ? (isArrayLike(object) && isIndex(index, object.length))
6342             : (type == 'string' && index in object)
6343           ) {
6344         return eq(object[index], value);
6345       }
6346       return false;
6347     }
6348
6349     /**
6350      * Checks if `value` is a property name and not a property path.
6351      *
6352      * @private
6353      * @param {*} value The value to check.
6354      * @param {Object} [object] The object to query keys on.
6355      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6356      */
6357     function isKey(value, object) {
6358       if (isArray(value)) {
6359         return false;
6360       }
6361       var type = typeof value;
6362       if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6363           value == null || isSymbol(value)) {
6364         return true;
6365       }
6366       return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6367         (object != null && value in Object(object));
6368     }
6369
6370     /**
6371      * Checks if `value` is suitable for use as unique object key.
6372      *
6373      * @private
6374      * @param {*} value The value to check.
6375      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6376      */
6377     function isKeyable(value) {
6378       var type = typeof value;
6379       return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6380         ? (value !== '__proto__')
6381         : (value === null);
6382     }
6383
6384     /**
6385      * Checks if `func` has a lazy counterpart.
6386      *
6387      * @private
6388      * @param {Function} func The function to check.
6389      * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6390      *  else `false`.
6391      */
6392     function isLaziable(func) {
6393       var funcName = getFuncName(func),
6394           other = lodash[funcName];
6395
6396       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6397         return false;
6398       }
6399       if (func === other) {
6400         return true;
6401       }
6402       var data = getData(other);
6403       return !!data && func === data[0];
6404     }
6405
6406     /**
6407      * Checks if `func` has its source masked.
6408      *
6409      * @private
6410      * @param {Function} func The function to check.
6411      * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6412      */
6413     function isMasked(func) {
6414       return !!maskSrcKey && (maskSrcKey in func);
6415     }
6416
6417     /**
6418      * Checks if `func` is capable of being masked.
6419      *
6420      * @private
6421      * @param {*} value The value to check.
6422      * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6423      */
6424     var isMaskable = coreJsData ? isFunction : stubFalse;
6425
6426     /**
6427      * Checks if `value` is likely a prototype object.
6428      *
6429      * @private
6430      * @param {*} value The value to check.
6431      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6432      */
6433     function isPrototype(value) {
6434       var Ctor = value && value.constructor,
6435           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6436
6437       return value === proto;
6438     }
6439
6440     /**
6441      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6442      *
6443      * @private
6444      * @param {*} value The value to check.
6445      * @returns {boolean} Returns `true` if `value` if suitable for strict
6446      *  equality comparisons, else `false`.
6447      */
6448     function isStrictComparable(value) {
6449       return value === value && !isObject(value);
6450     }
6451
6452     /**
6453      * A specialized version of `matchesProperty` for source values suitable
6454      * for strict equality comparisons, i.e. `===`.
6455      *
6456      * @private
6457      * @param {string} key The key of the property to get.
6458      * @param {*} srcValue The value to match.
6459      * @returns {Function} Returns the new spec function.
6460      */
6461     function matchesStrictComparable(key, srcValue) {
6462       return function(object) {
6463         if (object == null) {
6464           return false;
6465         }
6466         return object[key] === srcValue &&
6467           (srcValue !== undefined || (key in Object(object)));
6468       };
6469     }
6470
6471     /**
6472      * A specialized version of `_.memoize` which clears the memoized function's
6473      * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6474      *
6475      * @private
6476      * @param {Function} func The function to have its output memoized.
6477      * @returns {Function} Returns the new memoized function.
6478      */
6479     function memoizeCapped(func) {
6480       var result = memoize(func, function(key) {
6481         if (cache.size === MAX_MEMOIZE_SIZE) {
6482           cache.clear();
6483         }
6484         return key;
6485       });
6486
6487       var cache = result.cache;
6488       return result;
6489     }
6490
6491     /**
6492      * Merges the function metadata of `source` into `data`.
6493      *
6494      * Merging metadata reduces the number of wrappers used to invoke a function.
6495      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6496      * may be applied regardless of execution order. Methods like `_.ary` and
6497      * `_.rearg` modify function arguments, making the order in which they are
6498      * executed important, preventing the merging of metadata. However, we make
6499      * an exception for a safe combined case where curried functions have `_.ary`
6500      * and or `_.rearg` applied.
6501      *
6502      * @private
6503      * @param {Array} data The destination metadata.
6504      * @param {Array} source The source metadata.
6505      * @returns {Array} Returns `data`.
6506      */
6507     function mergeData(data, source) {
6508       var bitmask = data[1],
6509           srcBitmask = source[1],
6510           newBitmask = bitmask | srcBitmask,
6511           isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6512
6513       var isCombo =
6514         ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6515         ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6516         ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6517
6518       // Exit early if metadata can't be merged.
6519       if (!(isCommon || isCombo)) {
6520         return data;
6521       }
6522       // Use source `thisArg` if available.
6523       if (srcBitmask & WRAP_BIND_FLAG) {
6524         data[2] = source[2];
6525         // Set when currying a bound function.
6526         newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6527       }
6528       // Compose partial arguments.
6529       var value = source[3];
6530       if (value) {
6531         var partials = data[3];
6532         data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6533         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6534       }
6535       // Compose partial right arguments.
6536       value = source[5];
6537       if (value) {
6538         partials = data[5];
6539         data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6540         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6541       }
6542       // Use source `argPos` if available.
6543       value = source[7];
6544       if (value) {
6545         data[7] = value;
6546       }
6547       // Use source `ary` if it's smaller.
6548       if (srcBitmask & WRAP_ARY_FLAG) {
6549         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6550       }
6551       // Use source `arity` if one is not provided.
6552       if (data[9] == null) {
6553         data[9] = source[9];
6554       }
6555       // Use source `func` and merge bitmasks.
6556       data[0] = source[0];
6557       data[1] = newBitmask;
6558
6559       return data;
6560     }
6561
6562     /**
6563      * This function is like
6564      * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6565      * except that it includes inherited enumerable properties.
6566      *
6567      * @private
6568      * @param {Object} object The object to query.
6569      * @returns {Array} Returns the array of property names.
6570      */
6571     function nativeKeysIn(object) {
6572       var result = [];
6573       if (object != null) {
6574         for (var key in Object(object)) {
6575           result.push(key);
6576         }
6577       }
6578       return result;
6579     }
6580
6581     /**
6582      * Converts `value` to a string using `Object.prototype.toString`.
6583      *
6584      * @private
6585      * @param {*} value The value to convert.
6586      * @returns {string} Returns the converted string.
6587      */
6588     function objectToString(value) {
6589       return nativeObjectToString.call(value);
6590     }
6591
6592     /**
6593      * A specialized version of `baseRest` which transforms the rest array.
6594      *
6595      * @private
6596      * @param {Function} func The function to apply a rest parameter to.
6597      * @param {number} [start=func.length-1] The start position of the rest parameter.
6598      * @param {Function} transform The rest array transform.
6599      * @returns {Function} Returns the new function.
6600      */
6601     function overRest(func, start, transform) {
6602       start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6603       return function() {
6604         var args = arguments,
6605             index = -1,
6606             length = nativeMax(args.length - start, 0),
6607             array = Array(length);
6608
6609         while (++index < length) {
6610           array[index] = args[start + index];
6611         }
6612         index = -1;
6613         var otherArgs = Array(start + 1);
6614         while (++index < start) {
6615           otherArgs[index] = args[index];
6616         }
6617         otherArgs[start] = transform(array);
6618         return apply(func, this, otherArgs);
6619       };
6620     }
6621
6622     /**
6623      * Gets the parent value at `path` of `object`.
6624      *
6625      * @private
6626      * @param {Object} object The object to query.
6627      * @param {Array} path The path to get the parent value of.
6628      * @returns {*} Returns the parent value.
6629      */
6630     function parent(object, path) {
6631       return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6632     }
6633
6634     /**
6635      * Reorder `array` according to the specified indexes where the element at
6636      * the first index is assigned as the first element, the element at
6637      * the second index is assigned as the second element, and so on.
6638      *
6639      * @private
6640      * @param {Array} array The array to reorder.
6641      * @param {Array} indexes The arranged array indexes.
6642      * @returns {Array} Returns `array`.
6643      */
6644     function reorder(array, indexes) {
6645       var arrLength = array.length,
6646           length = nativeMin(indexes.length, arrLength),
6647           oldArray = copyArray(array);
6648
6649       while (length--) {
6650         var index = indexes[length];
6651         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6652       }
6653       return array;
6654     }
6655
6656     /**
6657      * Sets metadata for `func`.
6658      *
6659      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6660      * period of time, it will trip its breaker and transition to an identity
6661      * function to avoid garbage collection pauses in V8. See
6662      * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6663      * for more details.
6664      *
6665      * @private
6666      * @param {Function} func The function to associate metadata with.
6667      * @param {*} data The metadata.
6668      * @returns {Function} Returns `func`.
6669      */
6670     var setData = shortOut(baseSetData);
6671
6672     /**
6673      * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6674      *
6675      * @private
6676      * @param {Function} func The function to delay.
6677      * @param {number} wait The number of milliseconds to delay invocation.
6678      * @returns {number|Object} Returns the timer id or timeout object.
6679      */
6680     var setTimeout = ctxSetTimeout || function(func, wait) {
6681       return root.setTimeout(func, wait);
6682     };
6683
6684     /**
6685      * Sets the `toString` method of `func` to return `string`.
6686      *
6687      * @private
6688      * @param {Function} func The function to modify.
6689      * @param {Function} string The `toString` result.
6690      * @returns {Function} Returns `func`.
6691      */
6692     var setToString = shortOut(baseSetToString);
6693
6694     /**
6695      * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6696      * with wrapper details in a comment at the top of the source body.
6697      *
6698      * @private
6699      * @param {Function} wrapper The function to modify.
6700      * @param {Function} reference The reference function.
6701      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6702      * @returns {Function} Returns `wrapper`.
6703      */
6704     function setWrapToString(wrapper, reference, bitmask) {
6705       var source = (reference + '');
6706       return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6707     }
6708
6709     /**
6710      * Creates a function that'll short out and invoke `identity` instead
6711      * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6712      * milliseconds.
6713      *
6714      * @private
6715      * @param {Function} func The function to restrict.
6716      * @returns {Function} Returns the new shortable function.
6717      */
6718     function shortOut(func) {
6719       var count = 0,
6720           lastCalled = 0;
6721
6722       return function() {
6723         var stamp = nativeNow(),
6724             remaining = HOT_SPAN - (stamp - lastCalled);
6725
6726         lastCalled = stamp;
6727         if (remaining > 0) {
6728           if (++count >= HOT_COUNT) {
6729             return arguments[0];
6730           }
6731         } else {
6732           count = 0;
6733         }
6734         return func.apply(undefined, arguments);
6735       };
6736     }
6737
6738     /**
6739      * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6740      *
6741      * @private
6742      * @param {Array} array The array to shuffle.
6743      * @param {number} [size=array.length] The size of `array`.
6744      * @returns {Array} Returns `array`.
6745      */
6746     function shuffleSelf(array, size) {
6747       var index = -1,
6748           length = array.length,
6749           lastIndex = length - 1;
6750
6751       size = size === undefined ? length : size;
6752       while (++index < size) {
6753         var rand = baseRandom(index, lastIndex),
6754             value = array[rand];
6755
6756         array[rand] = array[index];
6757         array[index] = value;
6758       }
6759       array.length = size;
6760       return array;
6761     }
6762
6763     /**
6764      * Converts `string` to a property path array.
6765      *
6766      * @private
6767      * @param {string} string The string to convert.
6768      * @returns {Array} Returns the property path array.
6769      */
6770     var stringToPath = memoizeCapped(function(string) {
6771       var result = [];
6772       if (reLeadingDot.test(string)) {
6773         result.push('');
6774       }
6775       string.replace(rePropName, function(match, number, quote, string) {
6776         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
6777       });
6778       return result;
6779     });
6780
6781     /**
6782      * Converts `value` to a string key if it's not a string or symbol.
6783      *
6784      * @private
6785      * @param {*} value The value to inspect.
6786      * @returns {string|symbol} Returns the key.
6787      */
6788     function toKey(value) {
6789       if (typeof value == 'string' || isSymbol(value)) {
6790         return value;
6791       }
6792       var result = (value + '');
6793       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6794     }
6795
6796     /**
6797      * Converts `func` to its source code.
6798      *
6799      * @private
6800      * @param {Function} func The function to convert.
6801      * @returns {string} Returns the source code.
6802      */
6803     function toSource(func) {
6804       if (func != null) {
6805         try {
6806           return funcToString.call(func);
6807         } catch (e) {}
6808         try {
6809           return (func + '');
6810         } catch (e) {}
6811       }
6812       return '';
6813     }
6814
6815     /**
6816      * Updates wrapper `details` based on `bitmask` flags.
6817      *
6818      * @private
6819      * @returns {Array} details The details to modify.
6820      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6821      * @returns {Array} Returns `details`.
6822      */
6823     function updateWrapDetails(details, bitmask) {
6824       arrayEach(wrapFlags, function(pair) {
6825         var value = '_.' + pair[0];
6826         if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6827           details.push(value);
6828         }
6829       });
6830       return details.sort();
6831     }
6832
6833     /**
6834      * Creates a clone of `wrapper`.
6835      *
6836      * @private
6837      * @param {Object} wrapper The wrapper to clone.
6838      * @returns {Object} Returns the cloned wrapper.
6839      */
6840     function wrapperClone(wrapper) {
6841       if (wrapper instanceof LazyWrapper) {
6842         return wrapper.clone();
6843       }
6844       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6845       result.__actions__ = copyArray(wrapper.__actions__);
6846       result.__index__  = wrapper.__index__;
6847       result.__values__ = wrapper.__values__;
6848       return result;
6849     }
6850
6851     /*------------------------------------------------------------------------*/
6852
6853     /**
6854      * Creates an array of elements split into groups the length of `size`.
6855      * If `array` can't be split evenly, the final chunk will be the remaining
6856      * elements.
6857      *
6858      * @static
6859      * @memberOf _
6860      * @since 3.0.0
6861      * @category Array
6862      * @param {Array} array The array to process.
6863      * @param {number} [size=1] The length of each chunk
6864      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6865      * @returns {Array} Returns the new array of chunks.
6866      * @example
6867      *
6868      * _.chunk(['a', 'b', 'c', 'd'], 2);
6869      * // => [['a', 'b'], ['c', 'd']]
6870      *
6871      * _.chunk(['a', 'b', 'c', 'd'], 3);
6872      * // => [['a', 'b', 'c'], ['d']]
6873      */
6874     function chunk(array, size, guard) {
6875       if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6876         size = 1;
6877       } else {
6878         size = nativeMax(toInteger(size), 0);
6879       }
6880       var length = array == null ? 0 : array.length;
6881       if (!length || size < 1) {
6882         return [];
6883       }
6884       var index = 0,
6885           resIndex = 0,
6886           result = Array(nativeCeil(length / size));
6887
6888       while (index < length) {
6889         result[resIndex++] = baseSlice(array, index, (index += size));
6890       }
6891       return result;
6892     }
6893
6894     /**
6895      * Creates an array with all falsey values removed. The values `false`, `null`,
6896      * `0`, `""`, `undefined`, and `NaN` are falsey.
6897      *
6898      * @static
6899      * @memberOf _
6900      * @since 0.1.0
6901      * @category Array
6902      * @param {Array} array The array to compact.
6903      * @returns {Array} Returns the new array of filtered values.
6904      * @example
6905      *
6906      * _.compact([0, 1, false, 2, '', 3]);
6907      * // => [1, 2, 3]
6908      */
6909     function compact(array) {
6910       var index = -1,
6911           length = array == null ? 0 : array.length,
6912           resIndex = 0,
6913           result = [];
6914
6915       while (++index < length) {
6916         var value = array[index];
6917         if (value) {
6918           result[resIndex++] = value;
6919         }
6920       }
6921       return result;
6922     }
6923
6924     /**
6925      * Creates a new array concatenating `array` with any additional arrays
6926      * and/or values.
6927      *
6928      * @static
6929      * @memberOf _
6930      * @since 4.0.0
6931      * @category Array
6932      * @param {Array} array The array to concatenate.
6933      * @param {...*} [values] The values to concatenate.
6934      * @returns {Array} Returns the new concatenated array.
6935      * @example
6936      *
6937      * var array = [1];
6938      * var other = _.concat(array, 2, [3], [[4]]);
6939      *
6940      * console.log(other);
6941      * // => [1, 2, 3, [4]]
6942      *
6943      * console.log(array);
6944      * // => [1]
6945      */
6946     function concat() {
6947       var length = arguments.length;
6948       if (!length) {
6949         return [];
6950       }
6951       var args = Array(length - 1),
6952           array = arguments[0],
6953           index = length;
6954
6955       while (index--) {
6956         args[index - 1] = arguments[index];
6957       }
6958       return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6959     }
6960
6961     /**
6962      * Creates an array of `array` values not included in the other given arrays
6963      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6964      * for equality comparisons. The order and references of result values are
6965      * determined by the first array.
6966      *
6967      * **Note:** Unlike `_.pullAll`, this method returns a new array.
6968      *
6969      * @static
6970      * @memberOf _
6971      * @since 0.1.0
6972      * @category Array
6973      * @param {Array} array The array to inspect.
6974      * @param {...Array} [values] The values to exclude.
6975      * @returns {Array} Returns the new array of filtered values.
6976      * @see _.without, _.xor
6977      * @example
6978      *
6979      * _.difference([2, 1], [2, 3]);
6980      * // => [1]
6981      */
6982     var difference = baseRest(function(array, values) {
6983       return isArrayLikeObject(array)
6984         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6985         : [];
6986     });
6987
6988     /**
6989      * This method is like `_.difference` except that it accepts `iteratee` which
6990      * is invoked for each element of `array` and `values` to generate the criterion
6991      * by which they're compared. The order and references of result values are
6992      * determined by the first array. The iteratee is invoked with one argument:
6993      * (value).
6994      *
6995      * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
6996      *
6997      * @static
6998      * @memberOf _
6999      * @since 4.0.0
7000      * @category Array
7001      * @param {Array} array The array to inspect.
7002      * @param {...Array} [values] The values to exclude.
7003      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7004      * @returns {Array} Returns the new array of filtered values.
7005      * @example
7006      *
7007      * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7008      * // => [1.2]
7009      *
7010      * // The `_.property` iteratee shorthand.
7011      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
7012      * // => [{ 'x': 2 }]
7013      */
7014     var differenceBy = baseRest(function(array, values) {
7015       var iteratee = last(values);
7016       if (isArrayLikeObject(iteratee)) {
7017         iteratee = undefined;
7018       }
7019       return isArrayLikeObject(array)
7020         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7021         : [];
7022     });
7023
7024     /**
7025      * This method is like `_.difference` except that it accepts `comparator`
7026      * which is invoked to compare elements of `array` to `values`. The order and
7027      * references of result values are determined by the first array. The comparator
7028      * is invoked with two arguments: (arrVal, othVal).
7029      *
7030      * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7031      *
7032      * @static
7033      * @memberOf _
7034      * @since 4.0.0
7035      * @category Array
7036      * @param {Array} array The array to inspect.
7037      * @param {...Array} [values] The values to exclude.
7038      * @param {Function} [comparator] The comparator invoked per element.
7039      * @returns {Array} Returns the new array of filtered values.
7040      * @example
7041      *
7042      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7043      *
7044      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7045      * // => [{ 'x': 2, 'y': 1 }]
7046      */
7047     var differenceWith = baseRest(function(array, values) {
7048       var comparator = last(values);
7049       if (isArrayLikeObject(comparator)) {
7050         comparator = undefined;
7051       }
7052       return isArrayLikeObject(array)
7053         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7054         : [];
7055     });
7056
7057     /**
7058      * Creates a slice of `array` with `n` elements dropped from the beginning.
7059      *
7060      * @static
7061      * @memberOf _
7062      * @since 0.5.0
7063      * @category Array
7064      * @param {Array} array The array to query.
7065      * @param {number} [n=1] The number of elements to drop.
7066      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7067      * @returns {Array} Returns the slice of `array`.
7068      * @example
7069      *
7070      * _.drop([1, 2, 3]);
7071      * // => [2, 3]
7072      *
7073      * _.drop([1, 2, 3], 2);
7074      * // => [3]
7075      *
7076      * _.drop([1, 2, 3], 5);
7077      * // => []
7078      *
7079      * _.drop([1, 2, 3], 0);
7080      * // => [1, 2, 3]
7081      */
7082     function drop(array, n, guard) {
7083       var length = array == null ? 0 : array.length;
7084       if (!length) {
7085         return [];
7086       }
7087       n = (guard || n === undefined) ? 1 : toInteger(n);
7088       return baseSlice(array, n < 0 ? 0 : n, length);
7089     }
7090
7091     /**
7092      * Creates a slice of `array` with `n` elements dropped from the end.
7093      *
7094      * @static
7095      * @memberOf _
7096      * @since 3.0.0
7097      * @category Array
7098      * @param {Array} array The array to query.
7099      * @param {number} [n=1] The number of elements to drop.
7100      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7101      * @returns {Array} Returns the slice of `array`.
7102      * @example
7103      *
7104      * _.dropRight([1, 2, 3]);
7105      * // => [1, 2]
7106      *
7107      * _.dropRight([1, 2, 3], 2);
7108      * // => [1]
7109      *
7110      * _.dropRight([1, 2, 3], 5);
7111      * // => []
7112      *
7113      * _.dropRight([1, 2, 3], 0);
7114      * // => [1, 2, 3]
7115      */
7116     function dropRight(array, n, guard) {
7117       var length = array == null ? 0 : array.length;
7118       if (!length) {
7119         return [];
7120       }
7121       n = (guard || n === undefined) ? 1 : toInteger(n);
7122       n = length - n;
7123       return baseSlice(array, 0, n < 0 ? 0 : n);
7124     }
7125
7126     /**
7127      * Creates a slice of `array` excluding elements dropped from the end.
7128      * Elements are dropped until `predicate` returns falsey. The predicate is
7129      * invoked with three arguments: (value, index, array).
7130      *
7131      * @static
7132      * @memberOf _
7133      * @since 3.0.0
7134      * @category Array
7135      * @param {Array} array The array to query.
7136      * @param {Function} [predicate=_.identity] The function invoked per iteration.
7137      * @returns {Array} Returns the slice of `array`.
7138      * @example
7139      *
7140      * var users = [
7141      *   { 'user': 'barney',  'active': true },
7142      *   { 'user': 'fred',    'active': false },
7143      *   { 'user': 'pebbles', 'active': false }
7144      * ];
7145      *
7146      * _.dropRightWhile(users, function(o) { return !o.active; });
7147      * // => objects for ['barney']
7148      *
7149      * // The `_.matches` iteratee shorthand.
7150      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7151      * // => objects for ['barney', 'fred']
7152      *
7153      * // The `_.matchesProperty` iteratee shorthand.
7154      * _.dropRightWhile(users, ['active', false]);
7155      * // => objects for ['barney']
7156      *
7157      * // The `_.property` iteratee shorthand.
7158      * _.dropRightWhile(users, 'active');
7159      * // => objects for ['barney', 'fred', 'pebbles']
7160      */
7161     function dropRightWhile(array, predicate) {
7162       return (array && array.length)
7163         ? baseWhile(array, getIteratee(predicate, 3), true, true)
7164         : [];
7165     }
7166
7167     /**
7168      * Creates a slice of `array` excluding elements dropped from the beginning.
7169      * Elements are dropped until `predicate` returns falsey. The predicate is
7170      * invoked with three arguments: (value, index, array).
7171      *
7172      * @static
7173      * @memberOf _
7174      * @since 3.0.0
7175      * @category Array
7176      * @param {Array} array The array to query.
7177      * @param {Function} [predicate=_.identity] The function invoked per iteration.
7178      * @returns {Array} Returns the slice of `array`.
7179      * @example
7180      *
7181      * var users = [
7182      *   { 'user': 'barney',  'active': false },
7183      *   { 'user': 'fred',    'active': false },
7184      *   { 'user': 'pebbles', 'active': true }
7185      * ];
7186      *
7187      * _.dropWhile(users, function(o) { return !o.active; });
7188      * // => objects for ['pebbles']
7189      *
7190      * // The `_.matches` iteratee shorthand.
7191      * _.dropWhile(users, { 'user': 'barney', 'active': false });
7192      * // => objects for ['fred', 'pebbles']
7193      *
7194      * // The `_.matchesProperty` iteratee shorthand.
7195      * _.dropWhile(users, ['active', false]);
7196      * // => objects for ['pebbles']
7197      *
7198      * // The `_.property` iteratee shorthand.
7199      * _.dropWhile(users, 'active');
7200      * // => objects for ['barney', 'fred', 'pebbles']
7201      */
7202     function dropWhile(array, predicate) {
7203       return (array && array.length)
7204         ? baseWhile(array, getIteratee(predicate, 3), true)
7205         : [];
7206     }
7207
7208     /**
7209      * Fills elements of `array` with `value` from `start` up to, but not
7210      * including, `end`.
7211      *
7212      * **Note:** This method mutates `array`.
7213      *
7214      * @static
7215      * @memberOf _
7216      * @since 3.2.0
7217      * @category Array
7218      * @param {Array} array The array to fill.
7219      * @param {*} value The value to fill `array` with.
7220      * @param {number} [start=0] The start position.
7221      * @param {number} [end=array.length] The end position.
7222      * @returns {Array} Returns `array`.
7223      * @example
7224      *
7225      * var array = [1, 2, 3];
7226      *
7227      * _.fill(array, 'a');
7228      * console.log(array);
7229      * // => ['a', 'a', 'a']
7230      *
7231      * _.fill(Array(3), 2);
7232      * // => [2, 2, 2]
7233      *
7234      * _.fill([4, 6, 8, 10], '*', 1, 3);
7235      * // => [4, '*', '*', 10]
7236      */
7237     function fill(array, value, start, end) {
7238       var length = array == null ? 0 : array.length;
7239       if (!length) {
7240         return [];
7241       }
7242       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7243         start = 0;
7244         end = length;
7245       }
7246       return baseFill(array, value, start, end);
7247     }
7248
7249     /**
7250      * This method is like `_.find` except that it returns the index of the first
7251      * element `predicate` returns truthy for instead of the element itself.
7252      *
7253      * @static
7254      * @memberOf _
7255      * @since 1.1.0
7256      * @category Array
7257      * @param {Array} array The array to inspect.
7258      * @param {Function} [predicate=_.identity] The function invoked per iteration.
7259      * @param {number} [fromIndex=0] The index to search from.
7260      * @returns {number} Returns the index of the found element, else `-1`.
7261      * @example
7262      *
7263      * var users = [
7264      *   { 'user': 'barney',  'active': false },
7265      *   { 'user': 'fred',    'active': false },
7266      *   { 'user': 'pebbles', 'active': true }
7267      * ];
7268      *
7269      * _.findIndex(users, function(o) { return o.user == 'barney'; });
7270      * // => 0
7271      *
7272      * // The `_.matches` iteratee shorthand.
7273      * _.findIndex(users, { 'user': 'fred', 'active': false });
7274      * // => 1
7275      *
7276      * // The `_.matchesProperty` iteratee shorthand.
7277      * _.findIndex(users, ['active', false]);
7278      * // => 0
7279      *
7280      * // The `_.property` iteratee shorthand.
7281      * _.findIndex(users, 'active');
7282      * // => 2
7283      */
7284     function findIndex(array, predicate, fromIndex) {
7285       var length = array == null ? 0 : array.length;
7286       if (!length) {
7287         return -1;
7288       }
7289       var index = fromIndex == null ? 0 : toInteger(fromIndex);
7290       if (index < 0) {
7291         index = nativeMax(length + index, 0);
7292       }
7293       return baseFindIndex(array, getIteratee(predicate, 3), index);
7294     }
7295
7296     /**
7297      * This method is like `_.findIndex` except that it iterates over elements
7298      * of `collection` from right to left.
7299      *
7300      * @static
7301      * @memberOf _
7302      * @since 2.0.0
7303      * @category Array
7304      * @param {Array} array The array to inspect.
7305      * @param {Function} [predicate=_.identity] The function invoked per iteration.
7306      * @param {number} [fromIndex=array.length-1] The index to search from.
7307      * @returns {number} Returns the index of the found element, else `-1`.
7308      * @example
7309      *
7310      * var users = [
7311      *   { 'user': 'barney',  'active': true },
7312      *   { 'user': 'fred',    'active': false },
7313      *   { 'user': 'pebbles', 'active': false }
7314      * ];
7315      *
7316      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7317      * // => 2
7318      *
7319      * // The `_.matches` iteratee shorthand.
7320      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7321      * // => 0
7322      *
7323      * // The `_.matchesProperty` iteratee shorthand.
7324      * _.findLastIndex(users, ['active', false]);
7325      * // => 2
7326      *
7327      * // The `_.property` iteratee shorthand.
7328      * _.findLastIndex(users, 'active');
7329      * // => 0
7330      */
7331     function findLastIndex(array, predicate, fromIndex) {
7332       var length = array == null ? 0 : array.length;
7333       if (!length) {
7334         return -1;
7335       }
7336       var index = length - 1;
7337       if (fromIndex !== undefined) {
7338         index = toInteger(fromIndex);
7339         index = fromIndex < 0
7340           ? nativeMax(length + index, 0)
7341           : nativeMin(index, length - 1);
7342       }
7343       return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7344     }
7345
7346     /**
7347      * Flattens `array` a single level deep.
7348      *
7349      * @static
7350      * @memberOf _
7351      * @since 0.1.0
7352      * @category Array
7353      * @param {Array} array The array to flatten.
7354      * @returns {Array} Returns the new flattened array.
7355      * @example
7356      *
7357      * _.flatten([1, [2, [3, [4]], 5]]);
7358      * // => [1, 2, [3, [4]], 5]
7359      */
7360     function flatten(array) {
7361       var length = array == null ? 0 : array.length;
7362       return length ? baseFlatten(array, 1) : [];
7363     }
7364
7365     /**
7366      * Recursively flattens `array`.
7367      *
7368      * @static
7369      * @memberOf _
7370      * @since 3.0.0
7371      * @category Array
7372      * @param {Array} array The array to flatten.
7373      * @returns {Array} Returns the new flattened array.
7374      * @example
7375      *
7376      * _.flattenDeep([1, [2, [3, [4]], 5]]);
7377      * // => [1, 2, 3, 4, 5]
7378      */
7379     function flattenDeep(array) {
7380       var length = array == null ? 0 : array.length;
7381       return length ? baseFlatten(array, INFINITY) : [];
7382     }
7383
7384     /**
7385      * Recursively flatten `array` up to `depth` times.
7386      *
7387      * @static
7388      * @memberOf _
7389      * @since 4.4.0
7390      * @category Array
7391      * @param {Array} array The array to flatten.
7392      * @param {number} [depth=1] The maximum recursion depth.
7393      * @returns {Array} Returns the new flattened array.
7394      * @example
7395      *
7396      * var array = [1, [2, [3, [4]], 5]];
7397      *
7398      * _.flattenDepth(array, 1);
7399      * // => [1, 2, [3, [4]], 5]
7400      *
7401      * _.flattenDepth(array, 2);
7402      * // => [1, 2, 3, [4], 5]
7403      */
7404     function flattenDepth(array, depth) {
7405       var length = array == null ? 0 : array.length;
7406       if (!length) {
7407         return [];
7408       }
7409       depth = depth === undefined ? 1 : toInteger(depth);
7410       return baseFlatten(array, depth);
7411     }
7412
7413     /**
7414      * The inverse of `_.toPairs`; this method returns an object composed
7415      * from key-value `pairs`.
7416      *
7417      * @static
7418      * @memberOf _
7419      * @since 4.0.0
7420      * @category Array
7421      * @param {Array} pairs The key-value pairs.
7422      * @returns {Object} Returns the new object.
7423      * @example
7424      *
7425      * _.fromPairs([['a', 1], ['b', 2]]);
7426      * // => { 'a': 1, 'b': 2 }
7427      */
7428     function fromPairs(pairs) {
7429       var index = -1,
7430           length = pairs == null ? 0 : pairs.length,
7431           result = {};
7432
7433       while (++index < length) {
7434         var pair = pairs[index];
7435         result[pair[0]] = pair[1];
7436       }
7437       return result;
7438     }
7439
7440     /**
7441      * Gets the first element of `array`.
7442      *
7443      * @static
7444      * @memberOf _
7445      * @since 0.1.0
7446      * @alias first
7447      * @category Array
7448      * @param {Array} array The array to query.
7449      * @returns {*} Returns the first element of `array`.
7450      * @example
7451      *
7452      * _.head([1, 2, 3]);
7453      * // => 1
7454      *
7455      * _.head([]);
7456      * // => undefined
7457      */
7458     function head(array) {
7459       return (array && array.length) ? array[0] : undefined;
7460     }
7461
7462     /**
7463      * Gets the index at which the first occurrence of `value` is found in `array`
7464      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7465      * for equality comparisons. If `fromIndex` is negative, it's used as the
7466      * offset from the end of `array`.
7467      *
7468      * @static
7469      * @memberOf _
7470      * @since 0.1.0
7471      * @category Array
7472      * @param {Array} array The array to inspect.
7473      * @param {*} value The value to search for.
7474      * @param {number} [fromIndex=0] The index to search from.
7475      * @returns {number} Returns the index of the matched value, else `-1`.
7476      * @example
7477      *
7478      * _.indexOf([1, 2, 1, 2], 2);
7479      * // => 1
7480      *
7481      * // Search from the `fromIndex`.
7482      * _.indexOf([1, 2, 1, 2], 2, 2);
7483      * // => 3
7484      */
7485     function indexOf(array, value, fromIndex) {
7486       var length = array == null ? 0 : array.length;
7487       if (!length) {
7488         return -1;
7489       }
7490       var index = fromIndex == null ? 0 : toInteger(fromIndex);
7491       if (index < 0) {
7492         index = nativeMax(length + index, 0);
7493       }
7494       return baseIndexOf(array, value, index);
7495     }
7496
7497     /**
7498      * Gets all but the last element of `array`.
7499      *
7500      * @static
7501      * @memberOf _
7502      * @since 0.1.0
7503      * @category Array
7504      * @param {Array} array The array to query.
7505      * @returns {Array} Returns the slice of `array`.
7506      * @example
7507      *
7508      * _.initial([1, 2, 3]);
7509      * // => [1, 2]
7510      */
7511     function initial(array) {
7512       var length = array == null ? 0 : array.length;
7513       return length ? baseSlice(array, 0, -1) : [];
7514     }
7515
7516     /**
7517      * Creates an array of unique values that are included in all given arrays
7518      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7519      * for equality comparisons. The order and references of result values are
7520      * determined by the first array.
7521      *
7522      * @static
7523      * @memberOf _
7524      * @since 0.1.0
7525      * @category Array
7526      * @param {...Array} [arrays] The arrays to inspect.
7527      * @returns {Array} Returns the new array of intersecting values.
7528      * @example
7529      *
7530      * _.intersection([2, 1], [2, 3]);
7531      * // => [2]
7532      */
7533     var intersection = baseRest(function(arrays) {
7534       var mapped = arrayMap(arrays, castArrayLikeObject);
7535       return (mapped.length && mapped[0] === arrays[0])
7536         ? baseIntersection(mapped)
7537         : [];
7538     });
7539
7540     /**
7541      * This method is like `_.intersection` except that it accepts `iteratee`
7542      * which is invoked for each element of each `arrays` to generate the criterion
7543      * by which they're compared. The order and references of result values are
7544      * determined by the first array. The iteratee is invoked with one argument:
7545      * (value).
7546      *
7547      * @static
7548      * @memberOf _
7549      * @since 4.0.0
7550      * @category Array
7551      * @param {...Array} [arrays] The arrays to inspect.
7552      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7553      * @returns {Array} Returns the new array of intersecting values.
7554      * @example
7555      *
7556      * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7557      * // => [2.1]
7558      *
7559      * // The `_.property` iteratee shorthand.
7560      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7561      * // => [{ 'x': 1 }]
7562      */
7563     var intersectionBy = baseRest(function(arrays) {
7564       var iteratee = last(arrays),
7565           mapped = arrayMap(arrays, castArrayLikeObject);
7566
7567       if (iteratee === last(mapped)) {
7568         iteratee = undefined;
7569       } else {
7570         mapped.pop();
7571       }
7572       return (mapped.length && mapped[0] === arrays[0])
7573         ? baseIntersection(mapped, getIteratee(iteratee, 2))
7574         : [];
7575     });
7576
7577     /**
7578      * This method is like `_.intersection` except that it accepts `comparator`
7579      * which is invoked to compare elements of `arrays`. The order and references
7580      * of result values are determined by the first array. The comparator is
7581      * invoked with two arguments: (arrVal, othVal).
7582      *
7583      * @static
7584      * @memberOf _
7585      * @since 4.0.0
7586      * @category Array
7587      * @param {...Array} [arrays] The arrays to inspect.
7588      * @param {Function} [comparator] The comparator invoked per element.
7589      * @returns {Array} Returns the new array of intersecting values.
7590      * @example
7591      *
7592      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7593      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7594      *
7595      * _.intersectionWith(objects, others, _.isEqual);
7596      * // => [{ 'x': 1, 'y': 2 }]
7597      */
7598     var intersectionWith = baseRest(function(arrays) {
7599       var comparator = last(arrays),
7600           mapped = arrayMap(arrays, castArrayLikeObject);
7601
7602       comparator = typeof comparator == 'function' ? comparator : undefined;
7603       if (comparator) {
7604         mapped.pop();
7605       }
7606       return (mapped.length && mapped[0] === arrays[0])
7607         ? baseIntersection(mapped, undefined, comparator)
7608         : [];
7609     });
7610
7611     /**
7612      * Converts all elements in `array` into a string separated by `separator`.
7613      *
7614      * @static
7615      * @memberOf _
7616      * @since 4.0.0
7617      * @category Array
7618      * @param {Array} array The array to convert.
7619      * @param {string} [separator=','] The element separator.
7620      * @returns {string} Returns the joined string.
7621      * @example
7622      *
7623      * _.join(['a', 'b', 'c'], '~');
7624      * // => 'a~b~c'
7625      */
7626     function join(array, separator) {
7627       return array == null ? '' : nativeJoin.call(array, separator);
7628     }
7629
7630     /**
7631      * Gets the last element of `array`.
7632      *
7633      * @static
7634      * @memberOf _
7635      * @since 0.1.0
7636      * @category Array
7637      * @param {Array} array The array to query.
7638      * @returns {*} Returns the last element of `array`.
7639      * @example
7640      *
7641      * _.last([1, 2, 3]);
7642      * // => 3
7643      */
7644     function last(array) {
7645       var length = array == null ? 0 : array.length;
7646       return length ? array[length - 1] : undefined;
7647     }
7648
7649     /**
7650      * This method is like `_.indexOf` except that it iterates over elements of
7651      * `array` from right to left.
7652      *
7653      * @static
7654      * @memberOf _
7655      * @since 0.1.0
7656      * @category Array
7657      * @param {Array} array The array to inspect.
7658      * @param {*} value The value to search for.
7659      * @param {number} [fromIndex=array.length-1] The index to search from.
7660      * @returns {number} Returns the index of the matched value, else `-1`.
7661      * @example
7662      *
7663      * _.lastIndexOf([1, 2, 1, 2], 2);
7664      * // => 3
7665      *
7666      * // Search from the `fromIndex`.
7667      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7668      * // => 1
7669      */
7670     function lastIndexOf(array, value, fromIndex) {
7671       var length = array == null ? 0 : array.length;
7672       if (!length) {
7673         return -1;
7674       }
7675       var index = length;
7676       if (fromIndex !== undefined) {
7677         index = toInteger(fromIndex);
7678         index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7679       }
7680       return value === value
7681         ? strictLastIndexOf(array, value, index)
7682         : baseFindIndex(array, baseIsNaN, index, true);
7683     }
7684
7685     /**
7686      * Gets the element at index `n` of `array`. If `n` is negative, the nth
7687      * element from the end is returned.
7688      *
7689      * @static
7690      * @memberOf _
7691      * @since 4.11.0
7692      * @category Array
7693      * @param {Array} array The array to query.
7694      * @param {number} [n=0] The index of the element to return.
7695      * @returns {*} Returns the nth element of `array`.
7696      * @example
7697      *
7698      * var array = ['a', 'b', 'c', 'd'];
7699      *
7700      * _.nth(array, 1);
7701      * // => 'b'
7702      *
7703      * _.nth(array, -2);
7704      * // => 'c';
7705      */
7706     function nth(array, n) {
7707       return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7708     }
7709
7710     /**
7711      * Removes all given values from `array` using
7712      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7713      * for equality comparisons.
7714      *
7715      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7716      * to remove elements from an array by predicate.
7717      *
7718      * @static
7719      * @memberOf _
7720      * @since 2.0.0
7721      * @category Array
7722      * @param {Array} array The array to modify.
7723      * @param {...*} [values] The values to remove.
7724      * @returns {Array} Returns `array`.
7725      * @example
7726      *
7727      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7728      *
7729      * _.pull(array, 'a', 'c');
7730      * console.log(array);
7731      * // => ['b', 'b']
7732      */
7733     var pull = baseRest(pullAll);
7734
7735     /**
7736      * This method is like `_.pull` except that it accepts an array of values to remove.
7737      *
7738      * **Note:** Unlike `_.difference`, this method mutates `array`.
7739      *
7740      * @static
7741      * @memberOf _
7742      * @since 4.0.0
7743      * @category Array
7744      * @param {Array} array The array to modify.
7745      * @param {Array} values The values to remove.
7746      * @returns {Array} Returns `array`.
7747      * @example
7748      *
7749      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7750      *
7751      * _.pullAll(array, ['a', 'c']);
7752      * console.log(array);
7753      * // => ['b', 'b']
7754      */
7755     function pullAll(array, values) {
7756       return (array && array.length && values && values.length)
7757         ? basePullAll(array, values)
7758         : array;
7759     }
7760
7761     /**
7762      * This method is like `_.pullAll` except that it accepts `iteratee` which is
7763      * invoked for each element of `array` and `values` to generate the criterion
7764      * by which they're compared. The iteratee is invoked with one argument: (value).
7765      *
7766      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7767      *
7768      * @static
7769      * @memberOf _
7770      * @since 4.0.0
7771      * @category Array
7772      * @param {Array} array The array to modify.
7773      * @param {Array} values The values to remove.
7774      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7775      * @returns {Array} Returns `array`.
7776      * @example
7777      *
7778      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7779      *
7780      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7781      * console.log(array);
7782      * // => [{ 'x': 2 }]
7783      */
7784     function pullAllBy(array, values, iteratee) {
7785       return (array && array.length && values && values.length)
7786         ? basePullAll(array, values, getIteratee(iteratee, 2))
7787         : array;
7788     }
7789
7790     /**
7791      * This method is like `_.pullAll` except that it accepts `comparator` which
7792      * is invoked to compare elements of `array` to `values`. The comparator is
7793      * invoked with two arguments: (arrVal, othVal).
7794      *
7795      * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7796      *
7797      * @static
7798      * @memberOf _
7799      * @since 4.6.0
7800      * @category Array
7801      * @param {Array} array The array to modify.
7802      * @param {Array} values The values to remove.
7803      * @param {Function} [comparator] The comparator invoked per element.
7804      * @returns {Array} Returns `array`.
7805      * @example
7806      *
7807      * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7808      *
7809      * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7810      * console.log(array);
7811      * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7812      */
7813     function pullAllWith(array, values, comparator) {
7814       return (array && array.length && values && values.length)
7815         ? basePullAll(array, values, undefined, comparator)
7816         : array;
7817     }
7818
7819     /**
7820      * Removes elements from `array` corresponding to `indexes` and returns an
7821      * array of removed elements.
7822      *
7823      * **Note:** Unlike `_.at`, this method mutates `array`.
7824      *
7825      * @static
7826      * @memberOf _
7827      * @since 3.0.0
7828      * @category Array
7829      * @param {Array} array The array to modify.
7830      * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7831      * @returns {Array} Returns the new array of removed elements.
7832      * @example
7833      *
7834      * var array = ['a', 'b', 'c', 'd'];
7835      * var pulled = _.pullAt(array, [1, 3]);
7836      *
7837      * console.log(array);
7838      * // => ['a', 'c']
7839      *
7840      * console.log(pulled);
7841      * // => ['b', 'd']
7842      */
7843     var pullAt = flatRest(function(array, indexes) {
7844       var length = array == null ? 0 : array.length,
7845           result = baseAt(array, indexes);
7846
7847       basePullAt(array, arrayMap(indexes, function(index) {
7848         return isIndex(index, length) ? +index : index;
7849       }).sort(compareAscending));
7850
7851       return result;
7852     });
7853
7854     /**
7855      * Removes all elements from `array` that `predicate` returns truthy for
7856      * and returns an array of the removed elements. The predicate is invoked
7857      * with three arguments: (value, index, array).
7858      *
7859      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7860      * to pull elements from an array by value.
7861      *
7862      * @static
7863      * @memberOf _
7864      * @since 2.0.0
7865      * @category Array
7866      * @param {Array} array The array to modify.
7867      * @param {Function} [predicate=_.identity] The function invoked per iteration.
7868      * @returns {Array} Returns the new array of removed elements.
7869      * @example
7870      *
7871      * var array = [1, 2, 3, 4];
7872      * var evens = _.remove(array, function(n) {
7873      *   return n % 2 == 0;
7874      * });
7875      *
7876      * console.log(array);
7877      * // => [1, 3]
7878      *
7879      * console.log(evens);
7880      * // => [2, 4]
7881      */
7882     function remove(array, predicate) {
7883       var result = [];
7884       if (!(array && array.length)) {
7885         return result;
7886       }
7887       var index = -1,
7888           indexes = [],
7889           length = array.length;
7890
7891       predicate = getIteratee(predicate, 3);
7892       while (++index < length) {
7893         var value = array[index];
7894         if (predicate(value, index, array)) {
7895           result.push(value);
7896           indexes.push(index);
7897         }
7898       }
7899       basePullAt(array, indexes);
7900       return result;
7901     }
7902
7903     /**
7904      * Reverses `array` so that the first element becomes the last, the second
7905      * element becomes the second to last, and so on.
7906      *
7907      * **Note:** This method mutates `array` and is based on
7908      * [`Array#reverse`](https://mdn.io/Array/reverse).
7909      *
7910      * @static
7911      * @memberOf _
7912      * @since 4.0.0
7913      * @category Array
7914      * @param {Array} array The array to modify.
7915      * @returns {Array} Returns `array`.
7916      * @example
7917      *
7918      * var array = [1, 2, 3];
7919      *
7920      * _.reverse(array);
7921      * // => [3, 2, 1]
7922      *
7923      * console.log(array);
7924      * // => [3, 2, 1]
7925      */
7926     function reverse(array) {
7927       return array == null ? array : nativeReverse.call(array);
7928     }
7929
7930     /**
7931      * Creates a slice of `array` from `start` up to, but not including, `end`.
7932      *
7933      * **Note:** This method is used instead of
7934      * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7935      * returned.
7936      *
7937      * @static
7938      * @memberOf _
7939      * @since 3.0.0
7940      * @category Array
7941      * @param {Array} array The array to slice.
7942      * @param {number} [start=0] The start position.
7943      * @param {number} [end=array.length] The end position.
7944      * @returns {Array} Returns the slice of `array`.
7945      */
7946     function slice(array, start, end) {
7947       var length = array == null ? 0 : array.length;
7948       if (!length) {
7949         return [];
7950       }
7951       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7952         start = 0;
7953         end = length;
7954       }
7955       else {
7956         start = start == null ? 0 : toInteger(start);
7957         end = end === undefined ? length : toInteger(end);
7958       }
7959       return baseSlice(array, start, end);
7960     }
7961
7962     /**
7963      * Uses a binary search to determine the lowest index at which `value`
7964      * should be inserted into `array` in order to maintain its sort order.
7965      *
7966      * @static
7967      * @memberOf _
7968      * @since 0.1.0
7969      * @category Array
7970      * @param {Array} array The sorted array to inspect.
7971      * @param {*} value The value to evaluate.
7972      * @returns {number} Returns the index at which `value` should be inserted
7973      *  into `array`.
7974      * @example
7975      *
7976      * _.sortedIndex([30, 50], 40);
7977      * // => 1
7978      */
7979     function sortedIndex(array, value) {
7980       return baseSortedIndex(array, value);
7981     }
7982
7983     /**
7984      * This method is like `_.sortedIndex` except that it accepts `iteratee`
7985      * which is invoked for `value` and each element of `array` to compute their
7986      * sort ranking. The iteratee is invoked with one argument: (value).
7987      *
7988      * @static
7989      * @memberOf _
7990      * @since 4.0.0
7991      * @category Array
7992      * @param {Array} array The sorted array to inspect.
7993      * @param {*} value The value to evaluate.
7994      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7995      * @returns {number} Returns the index at which `value` should be inserted
7996      *  into `array`.
7997      * @example
7998      *
7999      * var objects = [{ 'x': 4 }, { 'x': 5 }];
8000      *
8001      * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8002      * // => 0
8003      *
8004      * // The `_.property` iteratee shorthand.
8005      * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
8006      * // => 0
8007      */
8008     function sortedIndexBy(array, value, iteratee) {
8009       return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
8010     }
8011
8012     /**
8013      * This method is like `_.indexOf` except that it performs a binary
8014      * search on a sorted `array`.
8015      *
8016      * @static
8017      * @memberOf _
8018      * @since 4.0.0
8019      * @category Array
8020      * @param {Array} array The array to inspect.
8021      * @param {*} value The value to search for.
8022      * @returns {number} Returns the index of the matched value, else `-1`.
8023      * @example
8024      *
8025      * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8026      * // => 1
8027      */
8028     function sortedIndexOf(array, value) {
8029       var length = array == null ? 0 : array.length;
8030       if (length) {
8031         var index = baseSortedIndex(array, value);
8032         if (index < length && eq(array[index], value)) {
8033           return index;
8034         }
8035       }
8036       return -1;
8037     }
8038
8039     /**
8040      * This method is like `_.sortedIndex` except that it returns the highest
8041      * index at which `value` should be inserted into `array` in order to
8042      * maintain its sort order.
8043      *
8044      * @static
8045      * @memberOf _
8046      * @since 3.0.0
8047      * @category Array
8048      * @param {Array} array The sorted array to inspect.
8049      * @param {*} value The value to evaluate.
8050      * @returns {number} Returns the index at which `value` should be inserted
8051      *  into `array`.
8052      * @example
8053      *
8054      * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8055      * // => 4
8056      */
8057     function sortedLastIndex(array, value) {
8058       return baseSortedIndex(array, value, true);
8059     }
8060
8061     /**
8062      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8063      * which is invoked for `value` and each element of `array` to compute their
8064      * sort ranking. The iteratee is invoked with one argument: (value).
8065      *
8066      * @static
8067      * @memberOf _
8068      * @since 4.0.0
8069      * @category Array
8070      * @param {Array} array The sorted array to inspect.
8071      * @param {*} value The value to evaluate.
8072      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8073      * @returns {number} Returns the index at which `value` should be inserted
8074      *  into `array`.
8075      * @example
8076      *
8077      * var objects = [{ 'x': 4 }, { 'x': 5 }];
8078      *
8079      * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8080      * // => 1
8081      *
8082      * // The `_.property` iteratee shorthand.
8083      * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8084      * // => 1
8085      */
8086     function sortedLastIndexBy(array, value, iteratee) {
8087       return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8088     }
8089
8090     /**
8091      * This method is like `_.lastIndexOf` except that it performs a binary
8092      * search on a sorted `array`.
8093      *
8094      * @static
8095      * @memberOf _
8096      * @since 4.0.0
8097      * @category Array
8098      * @param {Array} array The array to inspect.
8099      * @param {*} value The value to search for.
8100      * @returns {number} Returns the index of the matched value, else `-1`.
8101      * @example
8102      *
8103      * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8104      * // => 3
8105      */
8106     function sortedLastIndexOf(array, value) {
8107       var length = array == null ? 0 : array.length;
8108       if (length) {
8109         var index = baseSortedIndex(array, value, true) - 1;
8110         if (eq(array[index], value)) {
8111           return index;
8112         }
8113       }
8114       return -1;
8115     }
8116
8117     /**
8118      * This method is like `_.uniq` except that it's designed and optimized
8119      * for sorted arrays.
8120      *
8121      * @static
8122      * @memberOf _
8123      * @since 4.0.0
8124      * @category Array
8125      * @param {Array} array The array to inspect.
8126      * @returns {Array} Returns the new duplicate free array.
8127      * @example
8128      *
8129      * _.sortedUniq([1, 1, 2]);
8130      * // => [1, 2]
8131      */
8132     function sortedUniq(array) {
8133       return (array && array.length)
8134         ? baseSortedUniq(array)
8135         : [];
8136     }
8137
8138     /**
8139      * This method is like `_.uniqBy` except that it's designed and optimized
8140      * for sorted arrays.
8141      *
8142      * @static
8143      * @memberOf _
8144      * @since 4.0.0
8145      * @category Array
8146      * @param {Array} array The array to inspect.
8147      * @param {Function} [iteratee] The iteratee invoked per element.
8148      * @returns {Array} Returns the new duplicate free array.
8149      * @example
8150      *
8151      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8152      * // => [1.1, 2.3]
8153      */
8154     function sortedUniqBy(array, iteratee) {
8155       return (array && array.length)
8156         ? baseSortedUniq(array, getIteratee(iteratee, 2))
8157         : [];
8158     }
8159
8160     /**
8161      * Gets all but the first element of `array`.
8162      *
8163      * @static
8164      * @memberOf _
8165      * @since 4.0.0
8166      * @category Array
8167      * @param {Array} array The array to query.
8168      * @returns {Array} Returns the slice of `array`.
8169      * @example
8170      *
8171      * _.tail([1, 2, 3]);
8172      * // => [2, 3]
8173      */
8174     function tail(array) {
8175       var length = array == null ? 0 : array.length;
8176       return length ? baseSlice(array, 1, length) : [];
8177     }
8178
8179     /**
8180      * Creates a slice of `array` with `n` elements taken from the beginning.
8181      *
8182      * @static
8183      * @memberOf _
8184      * @since 0.1.0
8185      * @category Array
8186      * @param {Array} array The array to query.
8187      * @param {number} [n=1] The number of elements to take.
8188      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8189      * @returns {Array} Returns the slice of `array`.
8190      * @example
8191      *
8192      * _.take([1, 2, 3]);
8193      * // => [1]
8194      *
8195      * _.take([1, 2, 3], 2);
8196      * // => [1, 2]
8197      *
8198      * _.take([1, 2, 3], 5);
8199      * // => [1, 2, 3]
8200      *
8201      * _.take([1, 2, 3], 0);
8202      * // => []
8203      */
8204     function take(array, n, guard) {
8205       if (!(array && array.length)) {
8206         return [];
8207       }
8208       n = (guard || n === undefined) ? 1 : toInteger(n);
8209       return baseSlice(array, 0, n < 0 ? 0 : n);
8210     }
8211
8212     /**
8213      * Creates a slice of `array` with `n` elements taken from the end.
8214      *
8215      * @static
8216      * @memberOf _
8217      * @since 3.0.0
8218      * @category Array
8219      * @param {Array} array The array to query.
8220      * @param {number} [n=1] The number of elements to take.
8221      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8222      * @returns {Array} Returns the slice of `array`.
8223      * @example
8224      *
8225      * _.takeRight([1, 2, 3]);
8226      * // => [3]
8227      *
8228      * _.takeRight([1, 2, 3], 2);
8229      * // => [2, 3]
8230      *
8231      * _.takeRight([1, 2, 3], 5);
8232      * // => [1, 2, 3]
8233      *
8234      * _.takeRight([1, 2, 3], 0);
8235      * // => []
8236      */
8237     function takeRight(array, n, guard) {
8238       var length = array == null ? 0 : array.length;
8239       if (!length) {
8240         return [];
8241       }
8242       n = (guard || n === undefined) ? 1 : toInteger(n);
8243       n = length - n;
8244       return baseSlice(array, n < 0 ? 0 : n, length);
8245     }
8246
8247     /**
8248      * Creates a slice of `array` with elements taken from the end. Elements are
8249      * taken until `predicate` returns falsey. The predicate is invoked with
8250      * three arguments: (value, index, array).
8251      *
8252      * @static
8253      * @memberOf _
8254      * @since 3.0.0
8255      * @category Array
8256      * @param {Array} array The array to query.
8257      * @param {Function} [predicate=_.identity] The function invoked per iteration.
8258      * @returns {Array} Returns the slice of `array`.
8259      * @example
8260      *
8261      * var users = [
8262      *   { 'user': 'barney',  'active': true },
8263      *   { 'user': 'fred',    'active': false },
8264      *   { 'user': 'pebbles', 'active': false }
8265      * ];
8266      *
8267      * _.takeRightWhile(users, function(o) { return !o.active; });
8268      * // => objects for ['fred', 'pebbles']
8269      *
8270      * // The `_.matches` iteratee shorthand.
8271      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8272      * // => objects for ['pebbles']
8273      *
8274      * // The `_.matchesProperty` iteratee shorthand.
8275      * _.takeRightWhile(users, ['active', false]);
8276      * // => objects for ['fred', 'pebbles']
8277      *
8278      * // The `_.property` iteratee shorthand.
8279      * _.takeRightWhile(users, 'active');
8280      * // => []
8281      */
8282     function takeRightWhile(array, predicate) {
8283       return (array && array.length)
8284         ? baseWhile(array, getIteratee(predicate, 3), false, true)
8285         : [];
8286     }
8287
8288     /**
8289      * Creates a slice of `array` with elements taken from the beginning. Elements
8290      * are taken until `predicate` returns falsey. The predicate is invoked with
8291      * three arguments: (value, index, array).
8292      *
8293      * @static
8294      * @memberOf _
8295      * @since 3.0.0
8296      * @category Array
8297      * @param {Array} array The array to query.
8298      * @param {Function} [predicate=_.identity] The function invoked per iteration.
8299      * @returns {Array} Returns the slice of `array`.
8300      * @example
8301      *
8302      * var users = [
8303      *   { 'user': 'barney',  'active': false },
8304      *   { 'user': 'fred',    'active': false },
8305      *   { 'user': 'pebbles', 'active': true }
8306      * ];
8307      *
8308      * _.takeWhile(users, function(o) { return !o.active; });
8309      * // => objects for ['barney', 'fred']
8310      *
8311      * // The `_.matches` iteratee shorthand.
8312      * _.takeWhile(users, { 'user': 'barney', 'active': false });
8313      * // => objects for ['barney']
8314      *
8315      * // The `_.matchesProperty` iteratee shorthand.
8316      * _.takeWhile(users, ['active', false]);
8317      * // => objects for ['barney', 'fred']
8318      *
8319      * // The `_.property` iteratee shorthand.
8320      * _.takeWhile(users, 'active');
8321      * // => []
8322      */
8323     function takeWhile(array, predicate) {
8324       return (array && array.length)
8325         ? baseWhile(array, getIteratee(predicate, 3))
8326         : [];
8327     }
8328
8329     /**
8330      * Creates an array of unique values, in order, from all given arrays using
8331      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8332      * for equality comparisons.
8333      *
8334      * @static
8335      * @memberOf _
8336      * @since 0.1.0
8337      * @category Array
8338      * @param {...Array} [arrays] The arrays to inspect.
8339      * @returns {Array} Returns the new array of combined values.
8340      * @example
8341      *
8342      * _.union([2], [1, 2]);
8343      * // => [2, 1]
8344      */
8345     var union = baseRest(function(arrays) {
8346       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8347     });
8348
8349     /**
8350      * This method is like `_.union` except that it accepts `iteratee` which is
8351      * invoked for each element of each `arrays` to generate the criterion by
8352      * which uniqueness is computed. Result values are chosen from the first
8353      * array in which the value occurs. The iteratee is invoked with one argument:
8354      * (value).
8355      *
8356      * @static
8357      * @memberOf _
8358      * @since 4.0.0
8359      * @category Array
8360      * @param {...Array} [arrays] The arrays to inspect.
8361      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8362      * @returns {Array} Returns the new array of combined values.
8363      * @example
8364      *
8365      * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8366      * // => [2.1, 1.2]
8367      *
8368      * // The `_.property` iteratee shorthand.
8369      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8370      * // => [{ 'x': 1 }, { 'x': 2 }]
8371      */
8372     var unionBy = baseRest(function(arrays) {
8373       var iteratee = last(arrays);
8374       if (isArrayLikeObject(iteratee)) {
8375         iteratee = undefined;
8376       }
8377       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8378     });
8379
8380     /**
8381      * This method is like `_.union` except that it accepts `comparator` which
8382      * is invoked to compare elements of `arrays`. Result values are chosen from
8383      * the first array in which the value occurs. The comparator is invoked
8384      * with two arguments: (arrVal, othVal).
8385      *
8386      * @static
8387      * @memberOf _
8388      * @since 4.0.0
8389      * @category Array
8390      * @param {...Array} [arrays] The arrays to inspect.
8391      * @param {Function} [comparator] The comparator invoked per element.
8392      * @returns {Array} Returns the new array of combined values.
8393      * @example
8394      *
8395      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8396      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8397      *
8398      * _.unionWith(objects, others, _.isEqual);
8399      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8400      */
8401     var unionWith = baseRest(function(arrays) {
8402       var comparator = last(arrays);
8403       comparator = typeof comparator == 'function' ? comparator : undefined;
8404       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8405     });
8406
8407     /**
8408      * Creates a duplicate-free version of an array, using
8409      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8410      * for equality comparisons, in which only the first occurrence of each element
8411      * is kept. The order of result values is determined by the order they occur
8412      * in the array.
8413      *
8414      * @static
8415      * @memberOf _
8416      * @since 0.1.0
8417      * @category Array
8418      * @param {Array} array The array to inspect.
8419      * @returns {Array} Returns the new duplicate free array.
8420      * @example
8421      *
8422      * _.uniq([2, 1, 2]);
8423      * // => [2, 1]
8424      */
8425     function uniq(array) {
8426       return (array && array.length) ? baseUniq(array) : [];
8427     }
8428
8429     /**
8430      * This method is like `_.uniq` except that it accepts `iteratee` which is
8431      * invoked for each element in `array` to generate the criterion by which
8432      * uniqueness is computed. The order of result values is determined by the
8433      * order they occur in the array. The iteratee is invoked with one argument:
8434      * (value).
8435      *
8436      * @static
8437      * @memberOf _
8438      * @since 4.0.0
8439      * @category Array
8440      * @param {Array} array The array to inspect.
8441      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8442      * @returns {Array} Returns the new duplicate free array.
8443      * @example
8444      *
8445      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8446      * // => [2.1, 1.2]
8447      *
8448      * // The `_.property` iteratee shorthand.
8449      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8450      * // => [{ 'x': 1 }, { 'x': 2 }]
8451      */
8452     function uniqBy(array, iteratee) {
8453       return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8454     }
8455
8456     /**
8457      * This method is like `_.uniq` except that it accepts `comparator` which
8458      * is invoked to compare elements of `array`. The order of result values is
8459      * determined by the order they occur in the array.The comparator is invoked
8460      * with two arguments: (arrVal, othVal).
8461      *
8462      * @static
8463      * @memberOf _
8464      * @since 4.0.0
8465      * @category Array
8466      * @param {Array} array The array to inspect.
8467      * @param {Function} [comparator] The comparator invoked per element.
8468      * @returns {Array} Returns the new duplicate free array.
8469      * @example
8470      *
8471      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8472      *
8473      * _.uniqWith(objects, _.isEqual);
8474      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8475      */
8476     function uniqWith(array, comparator) {
8477       comparator = typeof comparator == 'function' ? comparator : undefined;
8478       return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8479     }
8480
8481     /**
8482      * This method is like `_.zip` except that it accepts an array of grouped
8483      * elements and creates an array regrouping the elements to their pre-zip
8484      * configuration.
8485      *
8486      * @static
8487      * @memberOf _
8488      * @since 1.2.0
8489      * @category Array
8490      * @param {Array} array The array of grouped elements to process.
8491      * @returns {Array} Returns the new array of regrouped elements.
8492      * @example
8493      *
8494      * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8495      * // => [['a', 1, true], ['b', 2, false]]
8496      *
8497      * _.unzip(zipped);
8498      * // => [['a', 'b'], [1, 2], [true, false]]
8499      */
8500     function unzip(array) {
8501       if (!(array && array.length)) {
8502         return [];
8503       }
8504       var length = 0;
8505       array = arrayFilter(array, function(group) {
8506         if (isArrayLikeObject(group)) {
8507           length = nativeMax(group.length, length);
8508           return true;
8509         }
8510       });
8511       return baseTimes(length, function(index) {
8512         return arrayMap(array, baseProperty(index));
8513       });
8514     }
8515
8516     /**
8517      * This method is like `_.unzip` except that it accepts `iteratee` to specify
8518      * how regrouped values should be combined. The iteratee is invoked with the
8519      * elements of each group: (...group).
8520      *
8521      * @static
8522      * @memberOf _
8523      * @since 3.8.0
8524      * @category Array
8525      * @param {Array} array The array of grouped elements to process.
8526      * @param {Function} [iteratee=_.identity] The function to combine
8527      *  regrouped values.
8528      * @returns {Array} Returns the new array of regrouped elements.
8529      * @example
8530      *
8531      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8532      * // => [[1, 10, 100], [2, 20, 200]]
8533      *
8534      * _.unzipWith(zipped, _.add);
8535      * // => [3, 30, 300]
8536      */
8537     function unzipWith(array, iteratee) {
8538       if (!(array && array.length)) {
8539         return [];
8540       }
8541       var result = unzip(array);
8542       if (iteratee == null) {
8543         return result;
8544       }
8545       return arrayMap(result, function(group) {
8546         return apply(iteratee, undefined, group);
8547       });
8548     }
8549
8550     /**
8551      * Creates an array excluding all given values using
8552      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8553      * for equality comparisons.
8554      *
8555      * **Note:** Unlike `_.pull`, this method returns a new array.
8556      *
8557      * @static
8558      * @memberOf _
8559      * @since 0.1.0
8560      * @category Array
8561      * @param {Array} array The array to inspect.
8562      * @param {...*} [values] The values to exclude.
8563      * @returns {Array} Returns the new array of filtered values.
8564      * @see _.difference, _.xor
8565      * @example
8566      *
8567      * _.without([2, 1, 2, 3], 1, 2);
8568      * // => [3]
8569      */
8570     var without = baseRest(function(array, values) {
8571       return isArrayLikeObject(array)
8572         ? baseDifference(array, values)
8573         : [];
8574     });
8575
8576     /**
8577      * Creates an array of unique values that is the
8578      * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8579      * of the given arrays. The order of result values is determined by the order
8580      * they occur in the arrays.
8581      *
8582      * @static
8583      * @memberOf _
8584      * @since 2.4.0
8585      * @category Array
8586      * @param {...Array} [arrays] The arrays to inspect.
8587      * @returns {Array} Returns the new array of filtered values.
8588      * @see _.difference, _.without
8589      * @example
8590      *
8591      * _.xor([2, 1], [2, 3]);
8592      * // => [1, 3]
8593      */
8594     var xor = baseRest(function(arrays) {
8595       return baseXor(arrayFilter(arrays, isArrayLikeObject));
8596     });
8597
8598     /**
8599      * This method is like `_.xor` except that it accepts `iteratee` which is
8600      * invoked for each element of each `arrays` to generate the criterion by
8601      * which by which they're compared. The order of result values is determined
8602      * by the order they occur in the arrays. The iteratee is invoked with one
8603      * argument: (value).
8604      *
8605      * @static
8606      * @memberOf _
8607      * @since 4.0.0
8608      * @category Array
8609      * @param {...Array} [arrays] The arrays to inspect.
8610      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8611      * @returns {Array} Returns the new array of filtered values.
8612      * @example
8613      *
8614      * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8615      * // => [1.2, 3.4]
8616      *
8617      * // The `_.property` iteratee shorthand.
8618      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8619      * // => [{ 'x': 2 }]
8620      */
8621     var xorBy = baseRest(function(arrays) {
8622       var iteratee = last(arrays);
8623       if (isArrayLikeObject(iteratee)) {
8624         iteratee = undefined;
8625       }
8626       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8627     });
8628
8629     /**
8630      * This method is like `_.xor` except that it accepts `comparator` which is
8631      * invoked to compare elements of `arrays`. The order of result values is
8632      * determined by the order they occur in the arrays. The comparator is invoked
8633      * with two arguments: (arrVal, othVal).
8634      *
8635      * @static
8636      * @memberOf _
8637      * @since 4.0.0
8638      * @category Array
8639      * @param {...Array} [arrays] The arrays to inspect.
8640      * @param {Function} [comparator] The comparator invoked per element.
8641      * @returns {Array} Returns the new array of filtered values.
8642      * @example
8643      *
8644      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8645      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8646      *
8647      * _.xorWith(objects, others, _.isEqual);
8648      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8649      */
8650     var xorWith = baseRest(function(arrays) {
8651       var comparator = last(arrays);
8652       comparator = typeof comparator == 'function' ? comparator : undefined;
8653       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8654     });
8655
8656     /**
8657      * Creates an array of grouped elements, the first of which contains the
8658      * first elements of the given arrays, the second of which contains the
8659      * second elements of the given arrays, and so on.
8660      *
8661      * @static
8662      * @memberOf _
8663      * @since 0.1.0
8664      * @category Array
8665      * @param {...Array} [arrays] The arrays to process.
8666      * @returns {Array} Returns the new array of grouped elements.
8667      * @example
8668      *
8669      * _.zip(['a', 'b'], [1, 2], [true, false]);
8670      * // => [['a', 1, true], ['b', 2, false]]
8671      */
8672     var zip = baseRest(unzip);
8673
8674     /**
8675      * This method is like `_.fromPairs` except that it accepts two arrays,
8676      * one of property identifiers and one of corresponding values.
8677      *
8678      * @static
8679      * @memberOf _
8680      * @since 0.4.0
8681      * @category Array
8682      * @param {Array} [props=[]] The property identifiers.
8683      * @param {Array} [values=[]] The property values.
8684      * @returns {Object} Returns the new object.
8685      * @example
8686      *
8687      * _.zipObject(['a', 'b'], [1, 2]);
8688      * // => { 'a': 1, 'b': 2 }
8689      */
8690     function zipObject(props, values) {
8691       return baseZipObject(props || [], values || [], assignValue);
8692     }
8693
8694     /**
8695      * This method is like `_.zipObject` except that it supports property paths.
8696      *
8697      * @static
8698      * @memberOf _
8699      * @since 4.1.0
8700      * @category Array
8701      * @param {Array} [props=[]] The property identifiers.
8702      * @param {Array} [values=[]] The property values.
8703      * @returns {Object} Returns the new object.
8704      * @example
8705      *
8706      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
8707      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
8708      */
8709     function zipObjectDeep(props, values) {
8710       return baseZipObject(props || [], values || [], baseSet);
8711     }
8712
8713     /**
8714      * This method is like `_.zip` except that it accepts `iteratee` to specify
8715      * how grouped values should be combined. The iteratee is invoked with the
8716      * elements of each group: (...group).
8717      *
8718      * @static
8719      * @memberOf _
8720      * @since 3.8.0
8721      * @category Array
8722      * @param {...Array} [arrays] The arrays to process.
8723      * @param {Function} [iteratee=_.identity] The function to combine
8724      *  grouped values.
8725      * @returns {Array} Returns the new array of grouped elements.
8726      * @example
8727      *
8728      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
8729      *   return a + b + c;
8730      * });
8731      * // => [111, 222]
8732      */
8733     var zipWith = baseRest(function(arrays) {
8734       var length = arrays.length,
8735           iteratee = length > 1 ? arrays[length - 1] : undefined;
8736
8737       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
8738       return unzipWith(arrays, iteratee);
8739     });
8740
8741     /*------------------------------------------------------------------------*/
8742
8743     /**
8744      * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8745      * chain sequences enabled. The result of such sequences must be unwrapped
8746      * with `_#value`.
8747      *
8748      * @static
8749      * @memberOf _
8750      * @since 1.3.0
8751      * @category Seq
8752      * @param {*} value The value to wrap.
8753      * @returns {Object} Returns the new `lodash` wrapper instance.
8754      * @example
8755      *
8756      * var users = [
8757      *   { 'user': 'barney',  'age': 36 },
8758      *   { 'user': 'fred',    'age': 40 },
8759      *   { 'user': 'pebbles', 'age': 1 }
8760      * ];
8761      *
8762      * var youngest = _
8763      *   .chain(users)
8764      *   .sortBy('age')
8765      *   .map(function(o) {
8766      *     return o.user + ' is ' + o.age;
8767      *   })
8768      *   .head()
8769      *   .value();
8770      * // => 'pebbles is 1'
8771      */
8772     function chain(value) {
8773       var result = lodash(value);
8774       result.__chain__ = true;
8775       return result;
8776     }
8777
8778     /**
8779      * This method invokes `interceptor` and returns `value`. The interceptor
8780      * is invoked with one argument; (value). The purpose of this method is to
8781      * "tap into" a method chain sequence in order to modify intermediate results.
8782      *
8783      * @static
8784      * @memberOf _
8785      * @since 0.1.0
8786      * @category Seq
8787      * @param {*} value The value to provide to `interceptor`.
8788      * @param {Function} interceptor The function to invoke.
8789      * @returns {*} Returns `value`.
8790      * @example
8791      *
8792      * _([1, 2, 3])
8793      *  .tap(function(array) {
8794      *    // Mutate input array.
8795      *    array.pop();
8796      *  })
8797      *  .reverse()
8798      *  .value();
8799      * // => [2, 1]
8800      */
8801     function tap(value, interceptor) {
8802       interceptor(value);
8803       return value;
8804     }
8805
8806     /**
8807      * This method is like `_.tap` except that it returns the result of `interceptor`.
8808      * The purpose of this method is to "pass thru" values replacing intermediate
8809      * results in a method chain sequence.
8810      *
8811      * @static
8812      * @memberOf _
8813      * @since 3.0.0
8814      * @category Seq
8815      * @param {*} value The value to provide to `interceptor`.
8816      * @param {Function} interceptor The function to invoke.
8817      * @returns {*} Returns the result of `interceptor`.
8818      * @example
8819      *
8820      * _('  abc  ')
8821      *  .chain()
8822      *  .trim()
8823      *  .thru(function(value) {
8824      *    return [value];
8825      *  })
8826      *  .value();
8827      * // => ['abc']
8828      */
8829     function thru(value, interceptor) {
8830       return interceptor(value);
8831     }
8832
8833     /**
8834      * This method is the wrapper version of `_.at`.
8835      *
8836      * @name at
8837      * @memberOf _
8838      * @since 1.0.0
8839      * @category Seq
8840      * @param {...(string|string[])} [paths] The property paths to pick.
8841      * @returns {Object} Returns the new `lodash` wrapper instance.
8842      * @example
8843      *
8844      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8845      *
8846      * _(object).at(['a[0].b.c', 'a[1]']).value();
8847      * // => [3, 4]
8848      */
8849     var wrapperAt = flatRest(function(paths) {
8850       var length = paths.length,
8851           start = length ? paths[0] : 0,
8852           value = this.__wrapped__,
8853           interceptor = function(object) { return baseAt(object, paths); };
8854
8855       if (length > 1 || this.__actions__.length ||
8856           !(value instanceof LazyWrapper) || !isIndex(start)) {
8857         return this.thru(interceptor);
8858       }
8859       value = value.slice(start, +start + (length ? 1 : 0));
8860       value.__actions__.push({
8861         'func': thru,
8862         'args': [interceptor],
8863         'thisArg': undefined
8864       });
8865       return new LodashWrapper(value, this.__chain__).thru(function(array) {
8866         if (length && !array.length) {
8867           array.push(undefined);
8868         }
8869         return array;
8870       });
8871     });
8872
8873     /**
8874      * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8875      *
8876      * @name chain
8877      * @memberOf _
8878      * @since 0.1.0
8879      * @category Seq
8880      * @returns {Object} Returns the new `lodash` wrapper instance.
8881      * @example
8882      *
8883      * var users = [
8884      *   { 'user': 'barney', 'age': 36 },
8885      *   { 'user': 'fred',   'age': 40 }
8886      * ];
8887      *
8888      * // A sequence without explicit chaining.
8889      * _(users).head();
8890      * // => { 'user': 'barney', 'age': 36 }
8891      *
8892      * // A sequence with explicit chaining.
8893      * _(users)
8894      *   .chain()
8895      *   .head()
8896      *   .pick('user')
8897      *   .value();
8898      * // => { 'user': 'barney' }
8899      */
8900     function wrapperChain() {
8901       return chain(this);
8902     }
8903
8904     /**
8905      * Executes the chain sequence and returns the wrapped result.
8906      *
8907      * @name commit
8908      * @memberOf _
8909      * @since 3.2.0
8910      * @category Seq
8911      * @returns {Object} Returns the new `lodash` wrapper instance.
8912      * @example
8913      *
8914      * var array = [1, 2];
8915      * var wrapped = _(array).push(3);
8916      *
8917      * console.log(array);
8918      * // => [1, 2]
8919      *
8920      * wrapped = wrapped.commit();
8921      * console.log(array);
8922      * // => [1, 2, 3]
8923      *
8924      * wrapped.last();
8925      * // => 3
8926      *
8927      * console.log(array);
8928      * // => [1, 2, 3]
8929      */
8930     function wrapperCommit() {
8931       return new LodashWrapper(this.value(), this.__chain__);
8932     }
8933
8934     /**
8935      * Gets the next value on a wrapped object following the
8936      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8937      *
8938      * @name next
8939      * @memberOf _
8940      * @since 4.0.0
8941      * @category Seq
8942      * @returns {Object} Returns the next iterator value.
8943      * @example
8944      *
8945      * var wrapped = _([1, 2]);
8946      *
8947      * wrapped.next();
8948      * // => { 'done': false, 'value': 1 }
8949      *
8950      * wrapped.next();
8951      * // => { 'done': false, 'value': 2 }
8952      *
8953      * wrapped.next();
8954      * // => { 'done': true, 'value': undefined }
8955      */
8956     function wrapperNext() {
8957       if (this.__values__ === undefined) {
8958         this.__values__ = toArray(this.value());
8959       }
8960       var done = this.__index__ >= this.__values__.length,
8961           value = done ? undefined : this.__values__[this.__index__++];
8962
8963       return { 'done': done, 'value': value };
8964     }
8965
8966     /**
8967      * Enables the wrapper to be iterable.
8968      *
8969      * @name Symbol.iterator
8970      * @memberOf _
8971      * @since 4.0.0
8972      * @category Seq
8973      * @returns {Object} Returns the wrapper object.
8974      * @example
8975      *
8976      * var wrapped = _([1, 2]);
8977      *
8978      * wrapped[Symbol.iterator]() === wrapped;
8979      * // => true
8980      *
8981      * Array.from(wrapped);
8982      * // => [1, 2]
8983      */
8984     function wrapperToIterator() {
8985       return this;
8986     }
8987
8988     /**
8989      * Creates a clone of the chain sequence planting `value` as the wrapped value.
8990      *
8991      * @name plant
8992      * @memberOf _
8993      * @since 3.2.0
8994      * @category Seq
8995      * @param {*} value The value to plant.
8996      * @returns {Object} Returns the new `lodash` wrapper instance.
8997      * @example
8998      *
8999      * function square(n) {
9000      *   return n * n;
9001      * }
9002      *
9003      * var wrapped = _([1, 2]).map(square);
9004      * var other = wrapped.plant([3, 4]);
9005      *
9006      * other.value();
9007      * // => [9, 16]
9008      *
9009      * wrapped.value();
9010      * // => [1, 4]
9011      */
9012     function wrapperPlant(value) {
9013       var result,
9014           parent = this;
9015
9016       while (parent instanceof baseLodash) {
9017         var clone = wrapperClone(parent);
9018         clone.__index__ = 0;
9019         clone.__values__ = undefined;
9020         if (result) {
9021           previous.__wrapped__ = clone;
9022         } else {
9023           result = clone;
9024         }
9025         var previous = clone;
9026         parent = parent.__wrapped__;
9027       }
9028       previous.__wrapped__ = value;
9029       return result;
9030     }
9031
9032     /**
9033      * This method is the wrapper version of `_.reverse`.
9034      *
9035      * **Note:** This method mutates the wrapped array.
9036      *
9037      * @name reverse
9038      * @memberOf _
9039      * @since 0.1.0
9040      * @category Seq
9041      * @returns {Object} Returns the new `lodash` wrapper instance.
9042      * @example
9043      *
9044      * var array = [1, 2, 3];
9045      *
9046      * _(array).reverse().value()
9047      * // => [3, 2, 1]
9048      *
9049      * console.log(array);
9050      * // => [3, 2, 1]
9051      */
9052     function wrapperReverse() {
9053       var value = this.__wrapped__;
9054       if (value instanceof LazyWrapper) {
9055         var wrapped = value;
9056         if (this.__actions__.length) {
9057           wrapped = new LazyWrapper(this);
9058         }
9059         wrapped = wrapped.reverse();
9060         wrapped.__actions__.push({
9061           'func': thru,
9062           'args': [reverse],
9063           'thisArg': undefined
9064         });
9065         return new LodashWrapper(wrapped, this.__chain__);
9066       }
9067       return this.thru(reverse);
9068     }
9069
9070     /**
9071      * Executes the chain sequence to resolve the unwrapped value.
9072      *
9073      * @name value
9074      * @memberOf _
9075      * @since 0.1.0
9076      * @alias toJSON, valueOf
9077      * @category Seq
9078      * @returns {*} Returns the resolved unwrapped value.
9079      * @example
9080      *
9081      * _([1, 2, 3]).value();
9082      * // => [1, 2, 3]
9083      */
9084     function wrapperValue() {
9085       return baseWrapperValue(this.__wrapped__, this.__actions__);
9086     }
9087
9088     /*------------------------------------------------------------------------*/
9089
9090     /**
9091      * Creates an object composed of keys generated from the results of running
9092      * each element of `collection` thru `iteratee`. The corresponding value of
9093      * each key is the number of times the key was returned by `iteratee`. The
9094      * iteratee is invoked with one argument: (value).
9095      *
9096      * @static
9097      * @memberOf _
9098      * @since 0.5.0
9099      * @category Collection
9100      * @param {Array|Object} collection The collection to iterate over.
9101      * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9102      * @returns {Object} Returns the composed aggregate object.
9103      * @example
9104      *
9105      * _.countBy([6.1, 4.2, 6.3], Math.floor);
9106      * // => { '4': 1, '6': 2 }
9107      *
9108      * // The `_.property` iteratee shorthand.
9109      * _.countBy(['one', 'two', 'three'], 'length');
9110      * // => { '3': 2, '5': 1 }
9111      */
9112     var countBy = createAggregator(function(result, value, key) {
9113       if (hasOwnProperty.call(result, key)) {
9114         ++result[key];
9115       } else {
9116         baseAssignValue(result, key, 1);
9117       }
9118     });
9119
9120     /**
9121      * Checks if `predicate` returns truthy for **all** elements of `collection`.
9122      * Iteration is stopped once `predicate` returns falsey. The predicate is
9123      * invoked with three arguments: (value, index|key, collection).
9124      *
9125      * **Note:** This method returns `true` for
9126      * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
9127      * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
9128      * elements of empty collections.
9129      *
9130      * @static
9131      * @memberOf _
9132      * @since 0.1.0
9133      * @category Collection
9134      * @param {Array|Object} collection The collection to iterate over.
9135      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9136      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9137      * @returns {boolean} Returns `true` if all elements pass the predicate check,
9138      *  else `false`.
9139      * @example
9140      *
9141      * _.every([true, 1, null, 'yes'], Boolean);
9142      * // => false
9143      *
9144      * var users = [
9145      *   { 'user': 'barney', 'age': 36, 'active': false },
9146      *   { 'user': 'fred',   'age': 40, 'active': false }
9147      * ];
9148      *
9149      * // The `_.matches` iteratee shorthand.
9150      * _.every(users, { 'user': 'barney', 'active': false });
9151      * // => false
9152      *
9153      * // The `_.matchesProperty` iteratee shorthand.
9154      * _.every(users, ['active', false]);
9155      * // => true
9156      *
9157      * // The `_.property` iteratee shorthand.
9158      * _.every(users, 'active');
9159      * // => false
9160      */
9161     function every(collection, predicate, guard) {
9162       var func = isArray(collection) ? arrayEvery : baseEvery;
9163       if (guard && isIterateeCall(collection, predicate, guard)) {
9164         predicate = undefined;
9165       }
9166       return func(collection, getIteratee(predicate, 3));
9167     }
9168
9169     /**
9170      * Iterates over elements of `collection`, returning an array of all elements
9171      * `predicate` returns truthy for. The predicate is invoked with three
9172      * arguments: (value, index|key, collection).
9173      *
9174      * **Note:** Unlike `_.remove`, this method returns a new array.
9175      *
9176      * @static
9177      * @memberOf _
9178      * @since 0.1.0
9179      * @category Collection
9180      * @param {Array|Object} collection The collection to iterate over.
9181      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9182      * @returns {Array} Returns the new filtered array.
9183      * @see _.reject
9184      * @example
9185      *
9186      * var users = [
9187      *   { 'user': 'barney', 'age': 36, 'active': true },
9188      *   { 'user': 'fred',   'age': 40, 'active': false }
9189      * ];
9190      *
9191      * _.filter(users, function(o) { return !o.active; });
9192      * // => objects for ['fred']
9193      *
9194      * // The `_.matches` iteratee shorthand.
9195      * _.filter(users, { 'age': 36, 'active': true });
9196      * // => objects for ['barney']
9197      *
9198      * // The `_.matchesProperty` iteratee shorthand.
9199      * _.filter(users, ['active', false]);
9200      * // => objects for ['fred']
9201      *
9202      * // The `_.property` iteratee shorthand.
9203      * _.filter(users, 'active');
9204      * // => objects for ['barney']
9205      */
9206     function filter(collection, predicate) {
9207       var func = isArray(collection) ? arrayFilter : baseFilter;
9208       return func(collection, getIteratee(predicate, 3));
9209     }
9210
9211     /**
9212      * Iterates over elements of `collection`, returning the first element
9213      * `predicate` returns truthy for. The predicate is invoked with three
9214      * arguments: (value, index|key, collection).
9215      *
9216      * @static
9217      * @memberOf _
9218      * @since 0.1.0
9219      * @category Collection
9220      * @param {Array|Object} collection The collection to inspect.
9221      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9222      * @param {number} [fromIndex=0] The index to search from.
9223      * @returns {*} Returns the matched element, else `undefined`.
9224      * @example
9225      *
9226      * var users = [
9227      *   { 'user': 'barney',  'age': 36, 'active': true },
9228      *   { 'user': 'fred',    'age': 40, 'active': false },
9229      *   { 'user': 'pebbles', 'age': 1,  'active': true }
9230      * ];
9231      *
9232      * _.find(users, function(o) { return o.age < 40; });
9233      * // => object for 'barney'
9234      *
9235      * // The `_.matches` iteratee shorthand.
9236      * _.find(users, { 'age': 1, 'active': true });
9237      * // => object for 'pebbles'
9238      *
9239      * // The `_.matchesProperty` iteratee shorthand.
9240      * _.find(users, ['active', false]);
9241      * // => object for 'fred'
9242      *
9243      * // The `_.property` iteratee shorthand.
9244      * _.find(users, 'active');
9245      * // => object for 'barney'
9246      */
9247     var find = createFind(findIndex);
9248
9249     /**
9250      * This method is like `_.find` except that it iterates over elements of
9251      * `collection` from right to left.
9252      *
9253      * @static
9254      * @memberOf _
9255      * @since 2.0.0
9256      * @category Collection
9257      * @param {Array|Object} collection The collection to inspect.
9258      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9259      * @param {number} [fromIndex=collection.length-1] The index to search from.
9260      * @returns {*} Returns the matched element, else `undefined`.
9261      * @example
9262      *
9263      * _.findLast([1, 2, 3, 4], function(n) {
9264      *   return n % 2 == 1;
9265      * });
9266      * // => 3
9267      */
9268     var findLast = createFind(findLastIndex);
9269
9270     /**
9271      * Creates a flattened array of values by running each element in `collection`
9272      * thru `iteratee` and flattening the mapped results. The iteratee is invoked
9273      * with three arguments: (value, index|key, collection).
9274      *
9275      * @static
9276      * @memberOf _
9277      * @since 4.0.0
9278      * @category Collection
9279      * @param {Array|Object} collection The collection to iterate over.
9280      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9281      * @returns {Array} Returns the new flattened array.
9282      * @example
9283      *
9284      * function duplicate(n) {
9285      *   return [n, n];
9286      * }
9287      *
9288      * _.flatMap([1, 2], duplicate);
9289      * // => [1, 1, 2, 2]
9290      */
9291     function flatMap(collection, iteratee) {
9292       return baseFlatten(map(collection, iteratee), 1);
9293     }
9294
9295     /**
9296      * This method is like `_.flatMap` except that it recursively flattens the
9297      * mapped results.
9298      *
9299      * @static
9300      * @memberOf _
9301      * @since 4.7.0
9302      * @category Collection
9303      * @param {Array|Object} collection The collection to iterate over.
9304      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9305      * @returns {Array} Returns the new flattened array.
9306      * @example
9307      *
9308      * function duplicate(n) {
9309      *   return [[[n, n]]];
9310      * }
9311      *
9312      * _.flatMapDeep([1, 2], duplicate);
9313      * // => [1, 1, 2, 2]
9314      */
9315     function flatMapDeep(collection, iteratee) {
9316       return baseFlatten(map(collection, iteratee), INFINITY);
9317     }
9318
9319     /**
9320      * This method is like `_.flatMap` except that it recursively flattens the
9321      * mapped results up to `depth` times.
9322      *
9323      * @static
9324      * @memberOf _
9325      * @since 4.7.0
9326      * @category Collection
9327      * @param {Array|Object} collection The collection to iterate over.
9328      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9329      * @param {number} [depth=1] The maximum recursion depth.
9330      * @returns {Array} Returns the new flattened array.
9331      * @example
9332      *
9333      * function duplicate(n) {
9334      *   return [[[n, n]]];
9335      * }
9336      *
9337      * _.flatMapDepth([1, 2], duplicate, 2);
9338      * // => [[1, 1], [2, 2]]
9339      */
9340     function flatMapDepth(collection, iteratee, depth) {
9341       depth = depth === undefined ? 1 : toInteger(depth);
9342       return baseFlatten(map(collection, iteratee), depth);
9343     }
9344
9345     /**
9346      * Iterates over elements of `collection` and invokes `iteratee` for each element.
9347      * The iteratee is invoked with three arguments: (value, index|key, collection).
9348      * Iteratee functions may exit iteration early by explicitly returning `false`.
9349      *
9350      * **Note:** As with other "Collections" methods, objects with a "length"
9351      * property are iterated like arrays. To avoid this behavior use `_.forIn`
9352      * or `_.forOwn` for object iteration.
9353      *
9354      * @static
9355      * @memberOf _
9356      * @since 0.1.0
9357      * @alias each
9358      * @category Collection
9359      * @param {Array|Object} collection The collection to iterate over.
9360      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9361      * @returns {Array|Object} Returns `collection`.
9362      * @see _.forEachRight
9363      * @example
9364      *
9365      * _.forEach([1, 2], function(value) {
9366      *   console.log(value);
9367      * });
9368      * // => Logs `1` then `2`.
9369      *
9370      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
9371      *   console.log(key);
9372      * });
9373      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
9374      */
9375     function forEach(collection, iteratee) {
9376       var func = isArray(collection) ? arrayEach : baseEach;
9377       return func(collection, getIteratee(iteratee, 3));
9378     }
9379
9380     /**
9381      * This method is like `_.forEach` except that it iterates over elements of
9382      * `collection` from right to left.
9383      *
9384      * @static
9385      * @memberOf _
9386      * @since 2.0.0
9387      * @alias eachRight
9388      * @category Collection
9389      * @param {Array|Object} collection The collection to iterate over.
9390      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9391      * @returns {Array|Object} Returns `collection`.
9392      * @see _.forEach
9393      * @example
9394      *
9395      * _.forEachRight([1, 2], function(value) {
9396      *   console.log(value);
9397      * });
9398      * // => Logs `2` then `1`.
9399      */
9400     function forEachRight(collection, iteratee) {
9401       var func = isArray(collection) ? arrayEachRight : baseEachRight;
9402       return func(collection, getIteratee(iteratee, 3));
9403     }
9404
9405     /**
9406      * Creates an object composed of keys generated from the results of running
9407      * each element of `collection` thru `iteratee`. The order of grouped values
9408      * is determined by the order they occur in `collection`. The corresponding
9409      * value of each key is an array of elements responsible for generating the
9410      * key. The iteratee is invoked with one argument: (value).
9411      *
9412      * @static
9413      * @memberOf _
9414      * @since 0.1.0
9415      * @category Collection
9416      * @param {Array|Object} collection The collection to iterate over.
9417      * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9418      * @returns {Object} Returns the composed aggregate object.
9419      * @example
9420      *
9421      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
9422      * // => { '4': [4.2], '6': [6.1, 6.3] }
9423      *
9424      * // The `_.property` iteratee shorthand.
9425      * _.groupBy(['one', 'two', 'three'], 'length');
9426      * // => { '3': ['one', 'two'], '5': ['three'] }
9427      */
9428     var groupBy = createAggregator(function(result, value, key) {
9429       if (hasOwnProperty.call(result, key)) {
9430         result[key].push(value);
9431       } else {
9432         baseAssignValue(result, key, [value]);
9433       }
9434     });
9435
9436     /**
9437      * Checks if `value` is in `collection`. If `collection` is a string, it's
9438      * checked for a substring of `value`, otherwise
9439      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9440      * is used for equality comparisons. If `fromIndex` is negative, it's used as
9441      * the offset from the end of `collection`.
9442      *
9443      * @static
9444      * @memberOf _
9445      * @since 0.1.0
9446      * @category Collection
9447      * @param {Array|Object|string} collection The collection to inspect.
9448      * @param {*} value The value to search for.
9449      * @param {number} [fromIndex=0] The index to search from.
9450      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9451      * @returns {boolean} Returns `true` if `value` is found, else `false`.
9452      * @example
9453      *
9454      * _.includes([1, 2, 3], 1);
9455      * // => true
9456      *
9457      * _.includes([1, 2, 3], 1, 2);
9458      * // => false
9459      *
9460      * _.includes({ 'a': 1, 'b': 2 }, 1);
9461      * // => true
9462      *
9463      * _.includes('abcd', 'bc');
9464      * // => true
9465      */
9466     function includes(collection, value, fromIndex, guard) {
9467       collection = isArrayLike(collection) ? collection : values(collection);
9468       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
9469
9470       var length = collection.length;
9471       if (fromIndex < 0) {
9472         fromIndex = nativeMax(length + fromIndex, 0);
9473       }
9474       return isString(collection)
9475         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
9476         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
9477     }
9478
9479     /**
9480      * Invokes the method at `path` of each element in `collection`, returning
9481      * an array of the results of each invoked method. Any additional arguments
9482      * are provided to each invoked method. If `path` is a function, it's invoked
9483      * for, and `this` bound to, each element in `collection`.
9484      *
9485      * @static
9486      * @memberOf _
9487      * @since 4.0.0
9488      * @category Collection
9489      * @param {Array|Object} collection The collection to iterate over.
9490      * @param {Array|Function|string} path The path of the method to invoke or
9491      *  the function invoked per iteration.
9492      * @param {...*} [args] The arguments to invoke each method with.
9493      * @returns {Array} Returns the array of results.
9494      * @example
9495      *
9496      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
9497      * // => [[1, 5, 7], [1, 2, 3]]
9498      *
9499      * _.invokeMap([123, 456], String.prototype.split, '');
9500      * // => [['1', '2', '3'], ['4', '5', '6']]
9501      */
9502     var invokeMap = baseRest(function(collection, path, args) {
9503       var index = -1,
9504           isFunc = typeof path == 'function',
9505           result = isArrayLike(collection) ? Array(collection.length) : [];
9506
9507       baseEach(collection, function(value) {
9508         result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
9509       });
9510       return result;
9511     });
9512
9513     /**
9514      * Creates an object composed of keys generated from the results of running
9515      * each element of `collection` thru `iteratee`. The corresponding value of
9516      * each key is the last element responsible for generating the key. The
9517      * iteratee is invoked with one argument: (value).
9518      *
9519      * @static
9520      * @memberOf _
9521      * @since 4.0.0
9522      * @category Collection
9523      * @param {Array|Object} collection The collection to iterate over.
9524      * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9525      * @returns {Object} Returns the composed aggregate object.
9526      * @example
9527      *
9528      * var array = [
9529      *   { 'dir': 'left', 'code': 97 },
9530      *   { 'dir': 'right', 'code': 100 }
9531      * ];
9532      *
9533      * _.keyBy(array, function(o) {
9534      *   return String.fromCharCode(o.code);
9535      * });
9536      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
9537      *
9538      * _.keyBy(array, 'dir');
9539      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
9540      */
9541     var keyBy = createAggregator(function(result, value, key) {
9542       baseAssignValue(result, key, value);
9543     });
9544
9545     /**
9546      * Creates an array of values by running each element in `collection` thru
9547      * `iteratee`. The iteratee is invoked with three arguments:
9548      * (value, index|key, collection).
9549      *
9550      * Many lodash methods are guarded to work as iteratees for methods like
9551      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
9552      *
9553      * The guarded methods are:
9554      * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
9555      * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
9556      * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
9557      * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
9558      *
9559      * @static
9560      * @memberOf _
9561      * @since 0.1.0
9562      * @category Collection
9563      * @param {Array|Object} collection The collection to iterate over.
9564      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9565      * @returns {Array} Returns the new mapped array.
9566      * @example
9567      *
9568      * function square(n) {
9569      *   return n * n;
9570      * }
9571      *
9572      * _.map([4, 8], square);
9573      * // => [16, 64]
9574      *
9575      * _.map({ 'a': 4, 'b': 8 }, square);
9576      * // => [16, 64] (iteration order is not guaranteed)
9577      *
9578      * var users = [
9579      *   { 'user': 'barney' },
9580      *   { 'user': 'fred' }
9581      * ];
9582      *
9583      * // The `_.property` iteratee shorthand.
9584      * _.map(users, 'user');
9585      * // => ['barney', 'fred']
9586      */
9587     function map(collection, iteratee) {
9588       var func = isArray(collection) ? arrayMap : baseMap;
9589       return func(collection, getIteratee(iteratee, 3));
9590     }
9591
9592     /**
9593      * This method is like `_.sortBy` except that it allows specifying the sort
9594      * orders of the iteratees to sort by. If `orders` is unspecified, all values
9595      * are sorted in ascending order. Otherwise, specify an order of "desc" for
9596      * descending or "asc" for ascending sort order of corresponding values.
9597      *
9598      * @static
9599      * @memberOf _
9600      * @since 4.0.0
9601      * @category Collection
9602      * @param {Array|Object} collection The collection to iterate over.
9603      * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
9604      *  The iteratees to sort by.
9605      * @param {string[]} [orders] The sort orders of `iteratees`.
9606      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9607      * @returns {Array} Returns the new sorted array.
9608      * @example
9609      *
9610      * var users = [
9611      *   { 'user': 'fred',   'age': 48 },
9612      *   { 'user': 'barney', 'age': 34 },
9613      *   { 'user': 'fred',   'age': 40 },
9614      *   { 'user': 'barney', 'age': 36 }
9615      * ];
9616      *
9617      * // Sort by `user` in ascending order and by `age` in descending order.
9618      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
9619      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9620      */
9621     function orderBy(collection, iteratees, orders, guard) {
9622       if (collection == null) {
9623         return [];
9624       }
9625       if (!isArray(iteratees)) {
9626         iteratees = iteratees == null ? [] : [iteratees];
9627       }
9628       orders = guard ? undefined : orders;
9629       if (!isArray(orders)) {
9630         orders = orders == null ? [] : [orders];
9631       }
9632       return baseOrderBy(collection, iteratees, orders);
9633     }
9634
9635     /**
9636      * Creates an array of elements split into two groups, the first of which
9637      * contains elements `predicate` returns truthy for, the second of which
9638      * contains elements `predicate` returns falsey for. The predicate is
9639      * invoked with one argument: (value).
9640      *
9641      * @static
9642      * @memberOf _
9643      * @since 3.0.0
9644      * @category Collection
9645      * @param {Array|Object} collection The collection to iterate over.
9646      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9647      * @returns {Array} Returns the array of grouped elements.
9648      * @example
9649      *
9650      * var users = [
9651      *   { 'user': 'barney',  'age': 36, 'active': false },
9652      *   { 'user': 'fred',    'age': 40, 'active': true },
9653      *   { 'user': 'pebbles', 'age': 1,  'active': false }
9654      * ];
9655      *
9656      * _.partition(users, function(o) { return o.active; });
9657      * // => objects for [['fred'], ['barney', 'pebbles']]
9658      *
9659      * // The `_.matches` iteratee shorthand.
9660      * _.partition(users, { 'age': 1, 'active': false });
9661      * // => objects for [['pebbles'], ['barney', 'fred']]
9662      *
9663      * // The `_.matchesProperty` iteratee shorthand.
9664      * _.partition(users, ['active', false]);
9665      * // => objects for [['barney', 'pebbles'], ['fred']]
9666      *
9667      * // The `_.property` iteratee shorthand.
9668      * _.partition(users, 'active');
9669      * // => objects for [['fred'], ['barney', 'pebbles']]
9670      */
9671     var partition = createAggregator(function(result, value, key) {
9672       result[key ? 0 : 1].push(value);
9673     }, function() { return [[], []]; });
9674
9675     /**
9676      * Reduces `collection` to a value which is the accumulated result of running
9677      * each element in `collection` thru `iteratee`, where each successive
9678      * invocation is supplied the return value of the previous. If `accumulator`
9679      * is not given, the first element of `collection` is used as the initial
9680      * value. The iteratee is invoked with four arguments:
9681      * (accumulator, value, index|key, collection).
9682      *
9683      * Many lodash methods are guarded to work as iteratees for methods like
9684      * `_.reduce`, `_.reduceRight`, and `_.transform`.
9685      *
9686      * The guarded methods are:
9687      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
9688      * and `sortBy`
9689      *
9690      * @static
9691      * @memberOf _
9692      * @since 0.1.0
9693      * @category Collection
9694      * @param {Array|Object} collection The collection to iterate over.
9695      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9696      * @param {*} [accumulator] The initial value.
9697      * @returns {*} Returns the accumulated value.
9698      * @see _.reduceRight
9699      * @example
9700      *
9701      * _.reduce([1, 2], function(sum, n) {
9702      *   return sum + n;
9703      * }, 0);
9704      * // => 3
9705      *
9706      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
9707      *   (result[value] || (result[value] = [])).push(key);
9708      *   return result;
9709      * }, {});
9710      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
9711      */
9712     function reduce(collection, iteratee, accumulator) {
9713       var func = isArray(collection) ? arrayReduce : baseReduce,
9714           initAccum = arguments.length < 3;
9715
9716       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
9717     }
9718
9719     /**
9720      * This method is like `_.reduce` except that it iterates over elements of
9721      * `collection` from right to left.
9722      *
9723      * @static
9724      * @memberOf _
9725      * @since 0.1.0
9726      * @category Collection
9727      * @param {Array|Object} collection The collection to iterate over.
9728      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9729      * @param {*} [accumulator] The initial value.
9730      * @returns {*} Returns the accumulated value.
9731      * @see _.reduce
9732      * @example
9733      *
9734      * var array = [[0, 1], [2, 3], [4, 5]];
9735      *
9736      * _.reduceRight(array, function(flattened, other) {
9737      *   return flattened.concat(other);
9738      * }, []);
9739      * // => [4, 5, 2, 3, 0, 1]
9740      */
9741     function reduceRight(collection, iteratee, accumulator) {
9742       var func = isArray(collection) ? arrayReduceRight : baseReduce,
9743           initAccum = arguments.length < 3;
9744
9745       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9746     }
9747
9748     /**
9749      * The opposite of `_.filter`; this method returns the elements of `collection`
9750      * that `predicate` does **not** return truthy for.
9751      *
9752      * @static
9753      * @memberOf _
9754      * @since 0.1.0
9755      * @category Collection
9756      * @param {Array|Object} collection The collection to iterate over.
9757      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9758      * @returns {Array} Returns the new filtered array.
9759      * @see _.filter
9760      * @example
9761      *
9762      * var users = [
9763      *   { 'user': 'barney', 'age': 36, 'active': false },
9764      *   { 'user': 'fred',   'age': 40, 'active': true }
9765      * ];
9766      *
9767      * _.reject(users, function(o) { return !o.active; });
9768      * // => objects for ['fred']
9769      *
9770      * // The `_.matches` iteratee shorthand.
9771      * _.reject(users, { 'age': 40, 'active': true });
9772      * // => objects for ['barney']
9773      *
9774      * // The `_.matchesProperty` iteratee shorthand.
9775      * _.reject(users, ['active', false]);
9776      * // => objects for ['fred']
9777      *
9778      * // The `_.property` iteratee shorthand.
9779      * _.reject(users, 'active');
9780      * // => objects for ['barney']
9781      */
9782     function reject(collection, predicate) {
9783       var func = isArray(collection) ? arrayFilter : baseFilter;
9784       return func(collection, negate(getIteratee(predicate, 3)));
9785     }
9786
9787     /**
9788      * Gets a random element from `collection`.
9789      *
9790      * @static
9791      * @memberOf _
9792      * @since 2.0.0
9793      * @category Collection
9794      * @param {Array|Object} collection The collection to sample.
9795      * @returns {*} Returns the random element.
9796      * @example
9797      *
9798      * _.sample([1, 2, 3, 4]);
9799      * // => 2
9800      */
9801     function sample(collection) {
9802       var func = isArray(collection) ? arraySample : baseSample;
9803       return func(collection);
9804     }
9805
9806     /**
9807      * Gets `n` random elements at unique keys from `collection` up to the
9808      * size of `collection`.
9809      *
9810      * @static
9811      * @memberOf _
9812      * @since 4.0.0
9813      * @category Collection
9814      * @param {Array|Object} collection The collection to sample.
9815      * @param {number} [n=1] The number of elements to sample.
9816      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9817      * @returns {Array} Returns the random elements.
9818      * @example
9819      *
9820      * _.sampleSize([1, 2, 3], 2);
9821      * // => [3, 1]
9822      *
9823      * _.sampleSize([1, 2, 3], 4);
9824      * // => [2, 3, 1]
9825      */
9826     function sampleSize(collection, n, guard) {
9827       if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9828         n = 1;
9829       } else {
9830         n = toInteger(n);
9831       }
9832       var func = isArray(collection) ? arraySampleSize : baseSampleSize;
9833       return func(collection, n);
9834     }
9835
9836     /**
9837      * Creates an array of shuffled values, using a version of the
9838      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9839      *
9840      * @static
9841      * @memberOf _
9842      * @since 0.1.0
9843      * @category Collection
9844      * @param {Array|Object} collection The collection to shuffle.
9845      * @returns {Array} Returns the new shuffled array.
9846      * @example
9847      *
9848      * _.shuffle([1, 2, 3, 4]);
9849      * // => [4, 1, 3, 2]
9850      */
9851     function shuffle(collection) {
9852       var func = isArray(collection) ? arrayShuffle : baseShuffle;
9853       return func(collection);
9854     }
9855
9856     /**
9857      * Gets the size of `collection` by returning its length for array-like
9858      * values or the number of own enumerable string keyed properties for objects.
9859      *
9860      * @static
9861      * @memberOf _
9862      * @since 0.1.0
9863      * @category Collection
9864      * @param {Array|Object|string} collection The collection to inspect.
9865      * @returns {number} Returns the collection size.
9866      * @example
9867      *
9868      * _.size([1, 2, 3]);
9869      * // => 3
9870      *
9871      * _.size({ 'a': 1, 'b': 2 });
9872      * // => 2
9873      *
9874      * _.size('pebbles');
9875      * // => 7
9876      */
9877     function size(collection) {
9878       if (collection == null) {
9879         return 0;
9880       }
9881       if (isArrayLike(collection)) {
9882         return isString(collection) ? stringSize(collection) : collection.length;
9883       }
9884       var tag = getTag(collection);
9885       if (tag == mapTag || tag == setTag) {
9886         return collection.size;
9887       }
9888       return baseKeys(collection).length;
9889     }
9890
9891     /**
9892      * Checks if `predicate` returns truthy for **any** element of `collection`.
9893      * Iteration is stopped once `predicate` returns truthy. The predicate is
9894      * invoked with three arguments: (value, index|key, collection).
9895      *
9896      * @static
9897      * @memberOf _
9898      * @since 0.1.0
9899      * @category Collection
9900      * @param {Array|Object} collection The collection to iterate over.
9901      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9902      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9903      * @returns {boolean} Returns `true` if any element passes the predicate check,
9904      *  else `false`.
9905      * @example
9906      *
9907      * _.some([null, 0, 'yes', false], Boolean);
9908      * // => true
9909      *
9910      * var users = [
9911      *   { 'user': 'barney', 'active': true },
9912      *   { 'user': 'fred',   'active': false }
9913      * ];
9914      *
9915      * // The `_.matches` iteratee shorthand.
9916      * _.some(users, { 'user': 'barney', 'active': false });
9917      * // => false
9918      *
9919      * // The `_.matchesProperty` iteratee shorthand.
9920      * _.some(users, ['active', false]);
9921      * // => true
9922      *
9923      * // The `_.property` iteratee shorthand.
9924      * _.some(users, 'active');
9925      * // => true
9926      */
9927     function some(collection, predicate, guard) {
9928       var func = isArray(collection) ? arraySome : baseSome;
9929       if (guard && isIterateeCall(collection, predicate, guard)) {
9930         predicate = undefined;
9931       }
9932       return func(collection, getIteratee(predicate, 3));
9933     }
9934
9935     /**
9936      * Creates an array of elements, sorted in ascending order by the results of
9937      * running each element in a collection thru each iteratee. This method
9938      * performs a stable sort, that is, it preserves the original sort order of
9939      * equal elements. The iteratees are invoked with one argument: (value).
9940      *
9941      * @static
9942      * @memberOf _
9943      * @since 0.1.0
9944      * @category Collection
9945      * @param {Array|Object} collection The collection to iterate over.
9946      * @param {...(Function|Function[])} [iteratees=[_.identity]]
9947      *  The iteratees to sort by.
9948      * @returns {Array} Returns the new sorted array.
9949      * @example
9950      *
9951      * var users = [
9952      *   { 'user': 'fred',   'age': 48 },
9953      *   { 'user': 'barney', 'age': 36 },
9954      *   { 'user': 'fred',   'age': 40 },
9955      *   { 'user': 'barney', 'age': 34 }
9956      * ];
9957      *
9958      * _.sortBy(users, [function(o) { return o.user; }]);
9959      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9960      *
9961      * _.sortBy(users, ['user', 'age']);
9962      * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9963      */
9964     var sortBy = baseRest(function(collection, iteratees) {
9965       if (collection == null) {
9966         return [];
9967       }
9968       var length = iteratees.length;
9969       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9970         iteratees = [];
9971       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9972         iteratees = [iteratees[0]];
9973       }
9974       return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
9975     });
9976
9977     /*------------------------------------------------------------------------*/
9978
9979     /**
9980      * Gets the timestamp of the number of milliseconds that have elapsed since
9981      * the Unix epoch (1 January 1970 00:00:00 UTC).
9982      *
9983      * @static
9984      * @memberOf _
9985      * @since 2.4.0
9986      * @category Date
9987      * @returns {number} Returns the timestamp.
9988      * @example
9989      *
9990      * _.defer(function(stamp) {
9991      *   console.log(_.now() - stamp);
9992      * }, _.now());
9993      * // => Logs the number of milliseconds it took for the deferred invocation.
9994      */
9995     var now = ctxNow || function() {
9996       return root.Date.now();
9997     };
9998
9999     /*------------------------------------------------------------------------*/
10000
10001     /**
10002      * The opposite of `_.before`; this method creates a function that invokes
10003      * `func` once it's called `n` or more times.
10004      *
10005      * @static
10006      * @memberOf _
10007      * @since 0.1.0
10008      * @category Function
10009      * @param {number} n The number of calls before `func` is invoked.
10010      * @param {Function} func The function to restrict.
10011      * @returns {Function} Returns the new restricted function.
10012      * @example
10013      *
10014      * var saves = ['profile', 'settings'];
10015      *
10016      * var done = _.after(saves.length, function() {
10017      *   console.log('done saving!');
10018      * });
10019      *
10020      * _.forEach(saves, function(type) {
10021      *   asyncSave({ 'type': type, 'complete': done });
10022      * });
10023      * // => Logs 'done saving!' after the two async saves have completed.
10024      */
10025     function after(n, func) {
10026       if (typeof func != 'function') {
10027         throw new TypeError(FUNC_ERROR_TEXT);
10028       }
10029       n = toInteger(n);
10030       return function() {
10031         if (--n < 1) {
10032           return func.apply(this, arguments);
10033         }
10034       };
10035     }
10036
10037     /**
10038      * Creates a function that invokes `func`, with up to `n` arguments,
10039      * ignoring any additional arguments.
10040      *
10041      * @static
10042      * @memberOf _
10043      * @since 3.0.0
10044      * @category Function
10045      * @param {Function} func The function to cap arguments for.
10046      * @param {number} [n=func.length] The arity cap.
10047      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10048      * @returns {Function} Returns the new capped function.
10049      * @example
10050      *
10051      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
10052      * // => [6, 8, 10]
10053      */
10054     function ary(func, n, guard) {
10055       n = guard ? undefined : n;
10056       n = (func && n == null) ? func.length : n;
10057       return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
10058     }
10059
10060     /**
10061      * Creates a function that invokes `func`, with the `this` binding and arguments
10062      * of the created function, while it's called less than `n` times. Subsequent
10063      * calls to the created function return the result of the last `func` invocation.
10064      *
10065      * @static
10066      * @memberOf _
10067      * @since 3.0.0
10068      * @category Function
10069      * @param {number} n The number of calls at which `func` is no longer invoked.
10070      * @param {Function} func The function to restrict.
10071      * @returns {Function} Returns the new restricted function.
10072      * @example
10073      *
10074      * jQuery(element).on('click', _.before(5, addContactToList));
10075      * // => Allows adding up to 4 contacts to the list.
10076      */
10077     function before(n, func) {
10078       var result;
10079       if (typeof func != 'function') {
10080         throw new TypeError(FUNC_ERROR_TEXT);
10081       }
10082       n = toInteger(n);
10083       return function() {
10084         if (--n > 0) {
10085           result = func.apply(this, arguments);
10086         }
10087         if (n <= 1) {
10088           func = undefined;
10089         }
10090         return result;
10091       };
10092     }
10093
10094     /**
10095      * Creates a function that invokes `func` with the `this` binding of `thisArg`
10096      * and `partials` prepended to the arguments it receives.
10097      *
10098      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
10099      * may be used as a placeholder for partially applied arguments.
10100      *
10101      * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
10102      * property of bound functions.
10103      *
10104      * @static
10105      * @memberOf _
10106      * @since 0.1.0
10107      * @category Function
10108      * @param {Function} func The function to bind.
10109      * @param {*} thisArg The `this` binding of `func`.
10110      * @param {...*} [partials] The arguments to be partially applied.
10111      * @returns {Function} Returns the new bound function.
10112      * @example
10113      *
10114      * function greet(greeting, punctuation) {
10115      *   return greeting + ' ' + this.user + punctuation;
10116      * }
10117      *
10118      * var object = { 'user': 'fred' };
10119      *
10120      * var bound = _.bind(greet, object, 'hi');
10121      * bound('!');
10122      * // => 'hi fred!'
10123      *
10124      * // Bound with placeholders.
10125      * var bound = _.bind(greet, object, _, '!');
10126      * bound('hi');
10127      * // => 'hi fred!'
10128      */
10129     var bind = baseRest(function(func, thisArg, partials) {
10130       var bitmask = WRAP_BIND_FLAG;
10131       if (partials.length) {
10132         var holders = replaceHolders(partials, getHolder(bind));
10133         bitmask |= WRAP_PARTIAL_FLAG;
10134       }
10135       return createWrap(func, bitmask, thisArg, partials, holders);
10136     });
10137
10138     /**
10139      * Creates a function that invokes the method at `object[key]` with `partials`
10140      * prepended to the arguments it receives.
10141      *
10142      * This method differs from `_.bind` by allowing bound functions to reference
10143      * methods that may be redefined or don't yet exist. See
10144      * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
10145      * for more details.
10146      *
10147      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
10148      * builds, may be used as a placeholder for partially applied arguments.
10149      *
10150      * @static
10151      * @memberOf _
10152      * @since 0.10.0
10153      * @category Function
10154      * @param {Object} object The object to invoke the method on.
10155      * @param {string} key The key of the method.
10156      * @param {...*} [partials] The arguments to be partially applied.
10157      * @returns {Function} Returns the new bound function.
10158      * @example
10159      *
10160      * var object = {
10161      *   'user': 'fred',
10162      *   'greet': function(greeting, punctuation) {
10163      *     return greeting + ' ' + this.user + punctuation;
10164      *   }
10165      * };
10166      *
10167      * var bound = _.bindKey(object, 'greet', 'hi');
10168      * bound('!');
10169      * // => 'hi fred!'
10170      *
10171      * object.greet = function(greeting, punctuation) {
10172      *   return greeting + 'ya ' + this.user + punctuation;
10173      * };
10174      *
10175      * bound('!');
10176      * // => 'hiya fred!'
10177      *
10178      * // Bound with placeholders.
10179      * var bound = _.bindKey(object, 'greet', _, '!');
10180      * bound('hi');
10181      * // => 'hiya fred!'
10182      */
10183     var bindKey = baseRest(function(object, key, partials) {
10184       var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10185       if (partials.length) {
10186         var holders = replaceHolders(partials, getHolder(bindKey));
10187         bitmask |= WRAP_PARTIAL_FLAG;
10188       }
10189       return createWrap(key, bitmask, object, partials, holders);
10190     });
10191
10192     /**
10193      * Creates a function that accepts arguments of `func` and either invokes
10194      * `func` returning its result, if at least `arity` number of arguments have
10195      * been provided, or returns a function that accepts the remaining `func`
10196      * arguments, and so on. The arity of `func` may be specified if `func.length`
10197      * is not sufficient.
10198      *
10199      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
10200      * may be used as a placeholder for provided arguments.
10201      *
10202      * **Note:** This method doesn't set the "length" property of curried functions.
10203      *
10204      * @static
10205      * @memberOf _
10206      * @since 2.0.0
10207      * @category Function
10208      * @param {Function} func The function to curry.
10209      * @param {number} [arity=func.length] The arity of `func`.
10210      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10211      * @returns {Function} Returns the new curried function.
10212      * @example
10213      *
10214      * var abc = function(a, b, c) {
10215      *   return [a, b, c];
10216      * };
10217      *
10218      * var curried = _.curry(abc);
10219      *
10220      * curried(1)(2)(3);
10221      * // => [1, 2, 3]
10222      *
10223      * curried(1, 2)(3);
10224      * // => [1, 2, 3]
10225      *
10226      * curried(1, 2, 3);
10227      * // => [1, 2, 3]
10228      *
10229      * // Curried with placeholders.
10230      * curried(1)(_, 3)(2);
10231      * // => [1, 2, 3]
10232      */
10233     function curry(func, arity, guard) {
10234       arity = guard ? undefined : arity;
10235       var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10236       result.placeholder = curry.placeholder;
10237       return result;
10238     }
10239
10240     /**
10241      * This method is like `_.curry` except that arguments are applied to `func`
10242      * in the manner of `_.partialRight` instead of `_.partial`.
10243      *
10244      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
10245      * builds, may be used as a placeholder for provided arguments.
10246      *
10247      * **Note:** This method doesn't set the "length" property of curried functions.
10248      *
10249      * @static
10250      * @memberOf _
10251      * @since 3.0.0
10252      * @category Function
10253      * @param {Function} func The function to curry.
10254      * @param {number} [arity=func.length] The arity of `func`.
10255      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10256      * @returns {Function} Returns the new curried function.
10257      * @example
10258      *
10259      * var abc = function(a, b, c) {
10260      *   return [a, b, c];
10261      * };
10262      *
10263      * var curried = _.curryRight(abc);
10264      *
10265      * curried(3)(2)(1);
10266      * // => [1, 2, 3]
10267      *
10268      * curried(2, 3)(1);
10269      * // => [1, 2, 3]
10270      *
10271      * curried(1, 2, 3);
10272      * // => [1, 2, 3]
10273      *
10274      * // Curried with placeholders.
10275      * curried(3)(1, _)(2);
10276      * // => [1, 2, 3]
10277      */
10278     function curryRight(func, arity, guard) {
10279       arity = guard ? undefined : arity;
10280       var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10281       result.placeholder = curryRight.placeholder;
10282       return result;
10283     }
10284
10285     /**
10286      * Creates a debounced function that delays invoking `func` until after `wait`
10287      * milliseconds have elapsed since the last time the debounced function was
10288      * invoked. The debounced function comes with a `cancel` method to cancel
10289      * delayed `func` invocations and a `flush` method to immediately invoke them.
10290      * Provide `options` to indicate whether `func` should be invoked on the
10291      * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
10292      * with the last arguments provided to the debounced function. Subsequent
10293      * calls to the debounced function return the result of the last `func`
10294      * invocation.
10295      *
10296      * **Note:** If `leading` and `trailing` options are `true`, `func` is
10297      * invoked on the trailing edge of the timeout only if the debounced function
10298      * is invoked more than once during the `wait` timeout.
10299      *
10300      * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10301      * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10302      *
10303      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10304      * for details over the differences between `_.debounce` and `_.throttle`.
10305      *
10306      * @static
10307      * @memberOf _
10308      * @since 0.1.0
10309      * @category Function
10310      * @param {Function} func The function to debounce.
10311      * @param {number} [wait=0] The number of milliseconds to delay.
10312      * @param {Object} [options={}] The options object.
10313      * @param {boolean} [options.leading=false]
10314      *  Specify invoking on the leading edge of the timeout.
10315      * @param {number} [options.maxWait]
10316      *  The maximum time `func` is allowed to be delayed before it's invoked.
10317      * @param {boolean} [options.trailing=true]
10318      *  Specify invoking on the trailing edge of the timeout.
10319      * @returns {Function} Returns the new debounced function.
10320      * @example
10321      *
10322      * // Avoid costly calculations while the window size is in flux.
10323      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
10324      *
10325      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
10326      * jQuery(element).on('click', _.debounce(sendMail, 300, {
10327      *   'leading': true,
10328      *   'trailing': false
10329      * }));
10330      *
10331      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
10332      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
10333      * var source = new EventSource('/stream');
10334      * jQuery(source).on('message', debounced);
10335      *
10336      * // Cancel the trailing debounced invocation.
10337      * jQuery(window).on('popstate', debounced.cancel);
10338      */
10339     function debounce(func, wait, options) {
10340       var lastArgs,
10341           lastThis,
10342           maxWait,
10343           result,
10344           timerId,
10345           lastCallTime,
10346           lastInvokeTime = 0,
10347           leading = false,
10348           maxing = false,
10349           trailing = true;
10350
10351       if (typeof func != 'function') {
10352         throw new TypeError(FUNC_ERROR_TEXT);
10353       }
10354       wait = toNumber(wait) || 0;
10355       if (isObject(options)) {
10356         leading = !!options.leading;
10357         maxing = 'maxWait' in options;
10358         maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
10359         trailing = 'trailing' in options ? !!options.trailing : trailing;
10360       }
10361
10362       function invokeFunc(time) {
10363         var args = lastArgs,
10364             thisArg = lastThis;
10365
10366         lastArgs = lastThis = undefined;
10367         lastInvokeTime = time;
10368         result = func.apply(thisArg, args);
10369         return result;
10370       }
10371
10372       function leadingEdge(time) {
10373         // Reset any `maxWait` timer.
10374         lastInvokeTime = time;
10375         // Start the timer for the trailing edge.
10376         timerId = setTimeout(timerExpired, wait);
10377         // Invoke the leading edge.
10378         return leading ? invokeFunc(time) : result;
10379       }
10380
10381       function remainingWait(time) {
10382         var timeSinceLastCall = time - lastCallTime,
10383             timeSinceLastInvoke = time - lastInvokeTime,
10384             result = wait - timeSinceLastCall;
10385
10386         return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
10387       }
10388
10389       function shouldInvoke(time) {
10390         var timeSinceLastCall = time - lastCallTime,
10391             timeSinceLastInvoke = time - lastInvokeTime;
10392
10393         // Either this is the first call, activity has stopped and we're at the
10394         // trailing edge, the system time has gone backwards and we're treating
10395         // it as the trailing edge, or we've hit the `maxWait` limit.
10396         return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
10397           (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
10398       }
10399
10400       function timerExpired() {
10401         var time = now();
10402         if (shouldInvoke(time)) {
10403           return trailingEdge(time);
10404         }
10405         // Restart the timer.
10406         timerId = setTimeout(timerExpired, remainingWait(time));
10407       }
10408
10409       function trailingEdge(time) {
10410         timerId = undefined;
10411
10412         // Only invoke if we have `lastArgs` which means `func` has been
10413         // debounced at least once.
10414         if (trailing && lastArgs) {
10415           return invokeFunc(time);
10416         }
10417         lastArgs = lastThis = undefined;
10418         return result;
10419       }
10420
10421       function cancel() {
10422         if (timerId !== undefined) {
10423           clearTimeout(timerId);
10424         }
10425         lastInvokeTime = 0;
10426         lastArgs = lastCallTime = lastThis = timerId = undefined;
10427       }
10428
10429       function flush() {
10430         return timerId === undefined ? result : trailingEdge(now());
10431       }
10432
10433       function debounced() {
10434         var time = now(),
10435             isInvoking = shouldInvoke(time);
10436
10437         lastArgs = arguments;
10438         lastThis = this;
10439         lastCallTime = time;
10440
10441         if (isInvoking) {
10442           if (timerId === undefined) {
10443             return leadingEdge(lastCallTime);
10444           }
10445           if (maxing) {
10446             // Handle invocations in a tight loop.
10447             timerId = setTimeout(timerExpired, wait);
10448             return invokeFunc(lastCallTime);
10449           }
10450         }
10451         if (timerId === undefined) {
10452           timerId = setTimeout(timerExpired, wait);
10453         }
10454         return result;
10455       }
10456       debounced.cancel = cancel;
10457       debounced.flush = flush;
10458       return debounced;
10459     }
10460
10461     /**
10462      * Defers invoking the `func` until the current call stack has cleared. Any
10463      * additional arguments are provided to `func` when it's invoked.
10464      *
10465      * @static
10466      * @memberOf _
10467      * @since 0.1.0
10468      * @category Function
10469      * @param {Function} func The function to defer.
10470      * @param {...*} [args] The arguments to invoke `func` with.
10471      * @returns {number} Returns the timer id.
10472      * @example
10473      *
10474      * _.defer(function(text) {
10475      *   console.log(text);
10476      * }, 'deferred');
10477      * // => Logs 'deferred' after one millisecond.
10478      */
10479     var defer = baseRest(function(func, args) {
10480       return baseDelay(func, 1, args);
10481     });
10482
10483     /**
10484      * Invokes `func` after `wait` milliseconds. Any additional arguments are
10485      * provided to `func` when it's invoked.
10486      *
10487      * @static
10488      * @memberOf _
10489      * @since 0.1.0
10490      * @category Function
10491      * @param {Function} func The function to delay.
10492      * @param {number} wait The number of milliseconds to delay invocation.
10493      * @param {...*} [args] The arguments to invoke `func` with.
10494      * @returns {number} Returns the timer id.
10495      * @example
10496      *
10497      * _.delay(function(text) {
10498      *   console.log(text);
10499      * }, 1000, 'later');
10500      * // => Logs 'later' after one second.
10501      */
10502     var delay = baseRest(function(func, wait, args) {
10503       return baseDelay(func, toNumber(wait) || 0, args);
10504     });
10505
10506     /**
10507      * Creates a function that invokes `func` with arguments reversed.
10508      *
10509      * @static
10510      * @memberOf _
10511      * @since 4.0.0
10512      * @category Function
10513      * @param {Function} func The function to flip arguments for.
10514      * @returns {Function} Returns the new flipped function.
10515      * @example
10516      *
10517      * var flipped = _.flip(function() {
10518      *   return _.toArray(arguments);
10519      * });
10520      *
10521      * flipped('a', 'b', 'c', 'd');
10522      * // => ['d', 'c', 'b', 'a']
10523      */
10524     function flip(func) {
10525       return createWrap(func, WRAP_FLIP_FLAG);
10526     }
10527
10528     /**
10529      * Creates a function that memoizes the result of `func`. If `resolver` is
10530      * provided, it determines the cache key for storing the result based on the
10531      * arguments provided to the memoized function. By default, the first argument
10532      * provided to the memoized function is used as the map cache key. The `func`
10533      * is invoked with the `this` binding of the memoized function.
10534      *
10535      * **Note:** The cache is exposed as the `cache` property on the memoized
10536      * function. Its creation may be customized by replacing the `_.memoize.Cache`
10537      * constructor with one whose instances implement the
10538      * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
10539      * method interface of `clear`, `delete`, `get`, `has`, and `set`.
10540      *
10541      * @static
10542      * @memberOf _
10543      * @since 0.1.0
10544      * @category Function
10545      * @param {Function} func The function to have its output memoized.
10546      * @param {Function} [resolver] The function to resolve the cache key.
10547      * @returns {Function} Returns the new memoized function.
10548      * @example
10549      *
10550      * var object = { 'a': 1, 'b': 2 };
10551      * var other = { 'c': 3, 'd': 4 };
10552      *
10553      * var values = _.memoize(_.values);
10554      * values(object);
10555      * // => [1, 2]
10556      *
10557      * values(other);
10558      * // => [3, 4]
10559      *
10560      * object.a = 2;
10561      * values(object);
10562      * // => [1, 2]
10563      *
10564      * // Modify the result cache.
10565      * values.cache.set(object, ['a', 'b']);
10566      * values(object);
10567      * // => ['a', 'b']
10568      *
10569      * // Replace `_.memoize.Cache`.
10570      * _.memoize.Cache = WeakMap;
10571      */
10572     function memoize(func, resolver) {
10573       if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
10574         throw new TypeError(FUNC_ERROR_TEXT);
10575       }
10576       var memoized = function() {
10577         var args = arguments,
10578             key = resolver ? resolver.apply(this, args) : args[0],
10579             cache = memoized.cache;
10580
10581         if (cache.has(key)) {
10582           return cache.get(key);
10583         }
10584         var result = func.apply(this, args);
10585         memoized.cache = cache.set(key, result) || cache;
10586         return result;
10587       };
10588       memoized.cache = new (memoize.Cache || MapCache);
10589       return memoized;
10590     }
10591
10592     // Expose `MapCache`.
10593     memoize.Cache = MapCache;
10594
10595     /**
10596      * Creates a function that negates the result of the predicate `func`. The
10597      * `func` predicate is invoked with the `this` binding and arguments of the
10598      * created function.
10599      *
10600      * @static
10601      * @memberOf _
10602      * @since 3.0.0
10603      * @category Function
10604      * @param {Function} predicate The predicate to negate.
10605      * @returns {Function} Returns the new negated function.
10606      * @example
10607      *
10608      * function isEven(n) {
10609      *   return n % 2 == 0;
10610      * }
10611      *
10612      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
10613      * // => [1, 3, 5]
10614      */
10615     function negate(predicate) {
10616       if (typeof predicate != 'function') {
10617         throw new TypeError(FUNC_ERROR_TEXT);
10618       }
10619       return function() {
10620         var args = arguments;
10621         switch (args.length) {
10622           case 0: return !predicate.call(this);
10623           case 1: return !predicate.call(this, args[0]);
10624           case 2: return !predicate.call(this, args[0], args[1]);
10625           case 3: return !predicate.call(this, args[0], args[1], args[2]);
10626         }
10627         return !predicate.apply(this, args);
10628       };
10629     }
10630
10631     /**
10632      * Creates a function that is restricted to invoking `func` once. Repeat calls
10633      * to the function return the value of the first invocation. The `func` is
10634      * invoked with the `this` binding and arguments of the created function.
10635      *
10636      * @static
10637      * @memberOf _
10638      * @since 0.1.0
10639      * @category Function
10640      * @param {Function} func The function to restrict.
10641      * @returns {Function} Returns the new restricted function.
10642      * @example
10643      *
10644      * var initialize = _.once(createApplication);
10645      * initialize();
10646      * initialize();
10647      * // => `createApplication` is invoked once
10648      */
10649     function once(func) {
10650       return before(2, func);
10651     }
10652
10653     /**
10654      * Creates a function that invokes `func` with its arguments transformed.
10655      *
10656      * @static
10657      * @since 4.0.0
10658      * @memberOf _
10659      * @category Function
10660      * @param {Function} func The function to wrap.
10661      * @param {...(Function|Function[])} [transforms=[_.identity]]
10662      *  The argument transforms.
10663      * @returns {Function} Returns the new function.
10664      * @example
10665      *
10666      * function doubled(n) {
10667      *   return n * 2;
10668      * }
10669      *
10670      * function square(n) {
10671      *   return n * n;
10672      * }
10673      *
10674      * var func = _.overArgs(function(x, y) {
10675      *   return [x, y];
10676      * }, [square, doubled]);
10677      *
10678      * func(9, 3);
10679      * // => [81, 6]
10680      *
10681      * func(10, 5);
10682      * // => [100, 10]
10683      */
10684     var overArgs = castRest(function(func, transforms) {
10685       transforms = (transforms.length == 1 && isArray(transforms[0]))
10686         ? arrayMap(transforms[0], baseUnary(getIteratee()))
10687         : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10688
10689       var funcsLength = transforms.length;
10690       return baseRest(function(args) {
10691         var index = -1,
10692             length = nativeMin(args.length, funcsLength);
10693
10694         while (++index < length) {
10695           args[index] = transforms[index].call(this, args[index]);
10696         }
10697         return apply(func, this, args);
10698       });
10699     });
10700
10701     /**
10702      * Creates a function that invokes `func` with `partials` prepended to the
10703      * arguments it receives. This method is like `_.bind` except it does **not**
10704      * alter the `this` binding.
10705      *
10706      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
10707      * builds, may be used as a placeholder for partially applied arguments.
10708      *
10709      * **Note:** This method doesn't set the "length" property of partially
10710      * applied functions.
10711      *
10712      * @static
10713      * @memberOf _
10714      * @since 0.2.0
10715      * @category Function
10716      * @param {Function} func The function to partially apply arguments to.
10717      * @param {...*} [partials] The arguments to be partially applied.
10718      * @returns {Function} Returns the new partially applied function.
10719      * @example
10720      *
10721      * function greet(greeting, name) {
10722      *   return greeting + ' ' + name;
10723      * }
10724      *
10725      * var sayHelloTo = _.partial(greet, 'hello');
10726      * sayHelloTo('fred');
10727      * // => 'hello fred'
10728      *
10729      * // Partially applied with placeholders.
10730      * var greetFred = _.partial(greet, _, 'fred');
10731      * greetFred('hi');
10732      * // => 'hi fred'
10733      */
10734     var partial = baseRest(function(func, partials) {
10735       var holders = replaceHolders(partials, getHolder(partial));
10736       return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
10737     });
10738
10739     /**
10740      * This method is like `_.partial` except that partially applied arguments
10741      * are appended to the arguments it receives.
10742      *
10743      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10744      * builds, may be used as a placeholder for partially applied arguments.
10745      *
10746      * **Note:** This method doesn't set the "length" property of partially
10747      * applied functions.
10748      *
10749      * @static
10750      * @memberOf _
10751      * @since 1.0.0
10752      * @category Function
10753      * @param {Function} func The function to partially apply arguments to.
10754      * @param {...*} [partials] The arguments to be partially applied.
10755      * @returns {Function} Returns the new partially applied function.
10756      * @example
10757      *
10758      * function greet(greeting, name) {
10759      *   return greeting + ' ' + name;
10760      * }
10761      *
10762      * var greetFred = _.partialRight(greet, 'fred');
10763      * greetFred('hi');
10764      * // => 'hi fred'
10765      *
10766      * // Partially applied with placeholders.
10767      * var sayHelloTo = _.partialRight(greet, 'hello', _);
10768      * sayHelloTo('fred');
10769      * // => 'hello fred'
10770      */
10771     var partialRight = baseRest(function(func, partials) {
10772       var holders = replaceHolders(partials, getHolder(partialRight));
10773       return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10774     });
10775
10776     /**
10777      * Creates a function that invokes `func` with arguments arranged according
10778      * to the specified `indexes` where the argument value at the first index is
10779      * provided as the first argument, the argument value at the second index is
10780      * provided as the second argument, and so on.
10781      *
10782      * @static
10783      * @memberOf _
10784      * @since 3.0.0
10785      * @category Function
10786      * @param {Function} func The function to rearrange arguments for.
10787      * @param {...(number|number[])} indexes The arranged argument indexes.
10788      * @returns {Function} Returns the new function.
10789      * @example
10790      *
10791      * var rearged = _.rearg(function(a, b, c) {
10792      *   return [a, b, c];
10793      * }, [2, 0, 1]);
10794      *
10795      * rearged('b', 'c', 'a')
10796      * // => ['a', 'b', 'c']
10797      */
10798     var rearg = flatRest(function(func, indexes) {
10799       return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
10800     });
10801
10802     /**
10803      * Creates a function that invokes `func` with the `this` binding of the
10804      * created function and arguments from `start` and beyond provided as
10805      * an array.
10806      *
10807      * **Note:** This method is based on the
10808      * [rest parameter](https://mdn.io/rest_parameters).
10809      *
10810      * @static
10811      * @memberOf _
10812      * @since 4.0.0
10813      * @category Function
10814      * @param {Function} func The function to apply a rest parameter to.
10815      * @param {number} [start=func.length-1] The start position of the rest parameter.
10816      * @returns {Function} Returns the new function.
10817      * @example
10818      *
10819      * var say = _.rest(function(what, names) {
10820      *   return what + ' ' + _.initial(names).join(', ') +
10821      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10822      * });
10823      *
10824      * say('hello', 'fred', 'barney', 'pebbles');
10825      * // => 'hello fred, barney, & pebbles'
10826      */
10827     function rest(func, start) {
10828       if (typeof func != 'function') {
10829         throw new TypeError(FUNC_ERROR_TEXT);
10830       }
10831       start = start === undefined ? start : toInteger(start);
10832       return baseRest(func, start);
10833     }
10834
10835     /**
10836      * Creates a function that invokes `func` with the `this` binding of the
10837      * create function and an array of arguments much like
10838      * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
10839      *
10840      * **Note:** This method is based on the
10841      * [spread operator](https://mdn.io/spread_operator).
10842      *
10843      * @static
10844      * @memberOf _
10845      * @since 3.2.0
10846      * @category Function
10847      * @param {Function} func The function to spread arguments over.
10848      * @param {number} [start=0] The start position of the spread.
10849      * @returns {Function} Returns the new function.
10850      * @example
10851      *
10852      * var say = _.spread(function(who, what) {
10853      *   return who + ' says ' + what;
10854      * });
10855      *
10856      * say(['fred', 'hello']);
10857      * // => 'fred says hello'
10858      *
10859      * var numbers = Promise.all([
10860      *   Promise.resolve(40),
10861      *   Promise.resolve(36)
10862      * ]);
10863      *
10864      * numbers.then(_.spread(function(x, y) {
10865      *   return x + y;
10866      * }));
10867      * // => a Promise of 76
10868      */
10869     function spread(func, start) {
10870       if (typeof func != 'function') {
10871         throw new TypeError(FUNC_ERROR_TEXT);
10872       }
10873       start = start == null ? 0 : nativeMax(toInteger(start), 0);
10874       return baseRest(function(args) {
10875         var array = args[start],
10876             otherArgs = castSlice(args, 0, start);
10877
10878         if (array) {
10879           arrayPush(otherArgs, array);
10880         }
10881         return apply(func, this, otherArgs);
10882       });
10883     }
10884
10885     /**
10886      * Creates a throttled function that only invokes `func` at most once per
10887      * every `wait` milliseconds. The throttled function comes with a `cancel`
10888      * method to cancel delayed `func` invocations and a `flush` method to
10889      * immediately invoke them. Provide `options` to indicate whether `func`
10890      * should be invoked on the leading and/or trailing edge of the `wait`
10891      * timeout. The `func` is invoked with the last arguments provided to the
10892      * throttled function. Subsequent calls to the throttled function return the
10893      * result of the last `func` invocation.
10894      *
10895      * **Note:** If `leading` and `trailing` options are `true`, `func` is
10896      * invoked on the trailing edge of the timeout only if the throttled function
10897      * is invoked more than once during the `wait` timeout.
10898      *
10899      * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10900      * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10901      *
10902      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10903      * for details over the differences between `_.throttle` and `_.debounce`.
10904      *
10905      * @static
10906      * @memberOf _
10907      * @since 0.1.0
10908      * @category Function
10909      * @param {Function} func The function to throttle.
10910      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10911      * @param {Object} [options={}] The options object.
10912      * @param {boolean} [options.leading=true]
10913      *  Specify invoking on the leading edge of the timeout.
10914      * @param {boolean} [options.trailing=true]
10915      *  Specify invoking on the trailing edge of the timeout.
10916      * @returns {Function} Returns the new throttled function.
10917      * @example
10918      *
10919      * // Avoid excessively updating the position while scrolling.
10920      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10921      *
10922      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10923      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10924      * jQuery(element).on('click', throttled);
10925      *
10926      * // Cancel the trailing throttled invocation.
10927      * jQuery(window).on('popstate', throttled.cancel);
10928      */
10929     function throttle(func, wait, options) {
10930       var leading = true,
10931           trailing = true;
10932
10933       if (typeof func != 'function') {
10934         throw new TypeError(FUNC_ERROR_TEXT);
10935       }
10936       if (isObject(options)) {
10937         leading = 'leading' in options ? !!options.leading : leading;
10938         trailing = 'trailing' in options ? !!options.trailing : trailing;
10939       }
10940       return debounce(func, wait, {
10941         'leading': leading,
10942         'maxWait': wait,
10943         'trailing': trailing
10944       });
10945     }
10946
10947     /**
10948      * Creates a function that accepts up to one argument, ignoring any
10949      * additional arguments.
10950      *
10951      * @static
10952      * @memberOf _
10953      * @since 4.0.0
10954      * @category Function
10955      * @param {Function} func The function to cap arguments for.
10956      * @returns {Function} Returns the new capped function.
10957      * @example
10958      *
10959      * _.map(['6', '8', '10'], _.unary(parseInt));
10960      * // => [6, 8, 10]
10961      */
10962     function unary(func) {
10963       return ary(func, 1);
10964     }
10965
10966     /**
10967      * Creates a function that provides `value` to `wrapper` as its first
10968      * argument. Any additional arguments provided to the function are appended
10969      * to those provided to the `wrapper`. The wrapper is invoked with the `this`
10970      * binding of the created function.
10971      *
10972      * @static
10973      * @memberOf _
10974      * @since 0.1.0
10975      * @category Function
10976      * @param {*} value The value to wrap.
10977      * @param {Function} [wrapper=identity] The wrapper function.
10978      * @returns {Function} Returns the new function.
10979      * @example
10980      *
10981      * var p = _.wrap(_.escape, function(func, text) {
10982      *   return '<p>' + func(text) + '</p>';
10983      * });
10984      *
10985      * p('fred, barney, & pebbles');
10986      * // => '<p>fred, barney, &amp; pebbles</p>'
10987      */
10988     function wrap(value, wrapper) {
10989       return partial(castFunction(wrapper), value);
10990     }
10991
10992     /*------------------------------------------------------------------------*/
10993
10994     /**
10995      * Casts `value` as an array if it's not one.
10996      *
10997      * @static
10998      * @memberOf _
10999      * @since 4.4.0
11000      * @category Lang
11001      * @param {*} value The value to inspect.
11002      * @returns {Array} Returns the cast array.
11003      * @example
11004      *
11005      * _.castArray(1);
11006      * // => [1]
11007      *
11008      * _.castArray({ 'a': 1 });
11009      * // => [{ 'a': 1 }]
11010      *
11011      * _.castArray('abc');
11012      * // => ['abc']
11013      *
11014      * _.castArray(null);
11015      * // => [null]
11016      *
11017      * _.castArray(undefined);
11018      * // => [undefined]
11019      *
11020      * _.castArray();
11021      * // => []
11022      *
11023      * var array = [1, 2, 3];
11024      * console.log(_.castArray(array) === array);
11025      * // => true
11026      */
11027     function castArray() {
11028       if (!arguments.length) {
11029         return [];
11030       }
11031       var value = arguments[0];
11032       return isArray(value) ? value : [value];
11033     }
11034
11035     /**
11036      * Creates a shallow clone of `value`.
11037      *
11038      * **Note:** This method is loosely based on the
11039      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
11040      * and supports cloning arrays, array buffers, booleans, date objects, maps,
11041      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
11042      * arrays. The own enumerable properties of `arguments` objects are cloned
11043      * as plain objects. An empty object is returned for uncloneable values such
11044      * as error objects, functions, DOM nodes, and WeakMaps.
11045      *
11046      * @static
11047      * @memberOf _
11048      * @since 0.1.0
11049      * @category Lang
11050      * @param {*} value The value to clone.
11051      * @returns {*} Returns the cloned value.
11052      * @see _.cloneDeep
11053      * @example
11054      *
11055      * var objects = [{ 'a': 1 }, { 'b': 2 }];
11056      *
11057      * var shallow = _.clone(objects);
11058      * console.log(shallow[0] === objects[0]);
11059      * // => true
11060      */
11061     function clone(value) {
11062       return baseClone(value, CLONE_SYMBOLS_FLAG);
11063     }
11064
11065     /**
11066      * This method is like `_.clone` except that it accepts `customizer` which
11067      * is invoked to produce the cloned value. If `customizer` returns `undefined`,
11068      * cloning is handled by the method instead. The `customizer` is invoked with
11069      * up to four arguments; (value [, index|key, object, stack]).
11070      *
11071      * @static
11072      * @memberOf _
11073      * @since 4.0.0
11074      * @category Lang
11075      * @param {*} value The value to clone.
11076      * @param {Function} [customizer] The function to customize cloning.
11077      * @returns {*} Returns the cloned value.
11078      * @see _.cloneDeepWith
11079      * @example
11080      *
11081      * function customizer(value) {
11082      *   if (_.isElement(value)) {
11083      *     return value.cloneNode(false);
11084      *   }
11085      * }
11086      *
11087      * var el = _.cloneWith(document.body, customizer);
11088      *
11089      * console.log(el === document.body);
11090      * // => false
11091      * console.log(el.nodeName);
11092      * // => 'BODY'
11093      * console.log(el.childNodes.length);
11094      * // => 0
11095      */
11096     function cloneWith(value, customizer) {
11097       customizer = typeof customizer == 'function' ? customizer : undefined;
11098       return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
11099     }
11100
11101     /**
11102      * This method is like `_.clone` except that it recursively clones `value`.
11103      *
11104      * @static
11105      * @memberOf _
11106      * @since 1.0.0
11107      * @category Lang
11108      * @param {*} value The value to recursively clone.
11109      * @returns {*} Returns the deep cloned value.
11110      * @see _.clone
11111      * @example
11112      *
11113      * var objects = [{ 'a': 1 }, { 'b': 2 }];
11114      *
11115      * var deep = _.cloneDeep(objects);
11116      * console.log(deep[0] === objects[0]);
11117      * // => false
11118      */
11119     function cloneDeep(value) {
11120       return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
11121     }
11122
11123     /**
11124      * This method is like `_.cloneWith` except that it recursively clones `value`.
11125      *
11126      * @static
11127      * @memberOf _
11128      * @since 4.0.0
11129      * @category Lang
11130      * @param {*} value The value to recursively clone.
11131      * @param {Function} [customizer] The function to customize cloning.
11132      * @returns {*} Returns the deep cloned value.
11133      * @see _.cloneWith
11134      * @example
11135      *
11136      * function customizer(value) {
11137      *   if (_.isElement(value)) {
11138      *     return value.cloneNode(true);
11139      *   }
11140      * }
11141      *
11142      * var el = _.cloneDeepWith(document.body, customizer);
11143      *
11144      * console.log(el === document.body);
11145      * // => false
11146      * console.log(el.nodeName);
11147      * // => 'BODY'
11148      * console.log(el.childNodes.length);
11149      * // => 20
11150      */
11151     function cloneDeepWith(value, customizer) {
11152       customizer = typeof customizer == 'function' ? customizer : undefined;
11153       return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
11154     }
11155
11156     /**
11157      * Checks if `object` conforms to `source` by invoking the predicate
11158      * properties of `source` with the corresponding property values of `object`.
11159      *
11160      * **Note:** This method is equivalent to `_.conforms` when `source` is
11161      * partially applied.
11162      *
11163      * @static
11164      * @memberOf _
11165      * @since 4.14.0
11166      * @category Lang
11167      * @param {Object} object The object to inspect.
11168      * @param {Object} source The object of property predicates to conform to.
11169      * @returns {boolean} Returns `true` if `object` conforms, else `false`.
11170      * @example
11171      *
11172      * var object = { 'a': 1, 'b': 2 };
11173      *
11174      * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
11175      * // => true
11176      *
11177      * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
11178      * // => false
11179      */
11180     function conformsTo(object, source) {
11181       return source == null || baseConformsTo(object, source, keys(source));
11182     }
11183
11184     /**
11185      * Performs a
11186      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
11187      * comparison between two values to determine if they are equivalent.
11188      *
11189      * @static
11190      * @memberOf _
11191      * @since 4.0.0
11192      * @category Lang
11193      * @param {*} value The value to compare.
11194      * @param {*} other The other value to compare.
11195      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11196      * @example
11197      *
11198      * var object = { 'a': 1 };
11199      * var other = { 'a': 1 };
11200      *
11201      * _.eq(object, object);
11202      * // => true
11203      *
11204      * _.eq(object, other);
11205      * // => false
11206      *
11207      * _.eq('a', 'a');
11208      * // => true
11209      *
11210      * _.eq('a', Object('a'));
11211      * // => false
11212      *
11213      * _.eq(NaN, NaN);
11214      * // => true
11215      */
11216     function eq(value, other) {
11217       return value === other || (value !== value && other !== other);
11218     }
11219
11220     /**
11221      * Checks if `value` is greater than `other`.
11222      *
11223      * @static
11224      * @memberOf _
11225      * @since 3.9.0
11226      * @category Lang
11227      * @param {*} value The value to compare.
11228      * @param {*} other The other value to compare.
11229      * @returns {boolean} Returns `true` if `value` is greater than `other`,
11230      *  else `false`.
11231      * @see _.lt
11232      * @example
11233      *
11234      * _.gt(3, 1);
11235      * // => true
11236      *
11237      * _.gt(3, 3);
11238      * // => false
11239      *
11240      * _.gt(1, 3);
11241      * // => false
11242      */
11243     var gt = createRelationalOperation(baseGt);
11244
11245     /**
11246      * Checks if `value` is greater than or equal to `other`.
11247      *
11248      * @static
11249      * @memberOf _
11250      * @since 3.9.0
11251      * @category Lang
11252      * @param {*} value The value to compare.
11253      * @param {*} other The other value to compare.
11254      * @returns {boolean} Returns `true` if `value` is greater than or equal to
11255      *  `other`, else `false`.
11256      * @see _.lte
11257      * @example
11258      *
11259      * _.gte(3, 1);
11260      * // => true
11261      *
11262      * _.gte(3, 3);
11263      * // => true
11264      *
11265      * _.gte(1, 3);
11266      * // => false
11267      */
11268     var gte = createRelationalOperation(function(value, other) {
11269       return value >= other;
11270     });
11271
11272     /**
11273      * Checks if `value` is likely an `arguments` object.
11274      *
11275      * @static
11276      * @memberOf _
11277      * @since 0.1.0
11278      * @category Lang
11279      * @param {*} value The value to check.
11280      * @returns {boolean} Returns `true` if `value` is an `arguments` object,
11281      *  else `false`.
11282      * @example
11283      *
11284      * _.isArguments(function() { return arguments; }());
11285      * // => true
11286      *
11287      * _.isArguments([1, 2, 3]);
11288      * // => false
11289      */
11290     var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
11291       return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
11292         !propertyIsEnumerable.call(value, 'callee');
11293     };
11294
11295     /**
11296      * Checks if `value` is classified as an `Array` object.
11297      *
11298      * @static
11299      * @memberOf _
11300      * @since 0.1.0
11301      * @category Lang
11302      * @param {*} value The value to check.
11303      * @returns {boolean} Returns `true` if `value` is an array, else `false`.
11304      * @example
11305      *
11306      * _.isArray([1, 2, 3]);
11307      * // => true
11308      *
11309      * _.isArray(document.body.children);
11310      * // => false
11311      *
11312      * _.isArray('abc');
11313      * // => false
11314      *
11315      * _.isArray(_.noop);
11316      * // => false
11317      */
11318     var isArray = Array.isArray;
11319
11320     /**
11321      * Checks if `value` is classified as an `ArrayBuffer` object.
11322      *
11323      * @static
11324      * @memberOf _
11325      * @since 4.3.0
11326      * @category Lang
11327      * @param {*} value The value to check.
11328      * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
11329      * @example
11330      *
11331      * _.isArrayBuffer(new ArrayBuffer(2));
11332      * // => true
11333      *
11334      * _.isArrayBuffer(new Array(2));
11335      * // => false
11336      */
11337     var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
11338
11339     /**
11340      * Checks if `value` is array-like. A value is considered array-like if it's
11341      * not a function and has a `value.length` that's an integer greater than or
11342      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
11343      *
11344      * @static
11345      * @memberOf _
11346      * @since 4.0.0
11347      * @category Lang
11348      * @param {*} value The value to check.
11349      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
11350      * @example
11351      *
11352      * _.isArrayLike([1, 2, 3]);
11353      * // => true
11354      *
11355      * _.isArrayLike(document.body.children);
11356      * // => true
11357      *
11358      * _.isArrayLike('abc');
11359      * // => true
11360      *
11361      * _.isArrayLike(_.noop);
11362      * // => false
11363      */
11364     function isArrayLike(value) {
11365       return value != null && isLength(value.length) && !isFunction(value);
11366     }
11367
11368     /**
11369      * This method is like `_.isArrayLike` except that it also checks if `value`
11370      * is an object.
11371      *
11372      * @static
11373      * @memberOf _
11374      * @since 4.0.0
11375      * @category Lang
11376      * @param {*} value The value to check.
11377      * @returns {boolean} Returns `true` if `value` is an array-like object,
11378      *  else `false`.
11379      * @example
11380      *
11381      * _.isArrayLikeObject([1, 2, 3]);
11382      * // => true
11383      *
11384      * _.isArrayLikeObject(document.body.children);
11385      * // => true
11386      *
11387      * _.isArrayLikeObject('abc');
11388      * // => false
11389      *
11390      * _.isArrayLikeObject(_.noop);
11391      * // => false
11392      */
11393     function isArrayLikeObject(value) {
11394       return isObjectLike(value) && isArrayLike(value);
11395     }
11396
11397     /**
11398      * Checks if `value` is classified as a boolean primitive or object.
11399      *
11400      * @static
11401      * @memberOf _
11402      * @since 0.1.0
11403      * @category Lang
11404      * @param {*} value The value to check.
11405      * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
11406      * @example
11407      *
11408      * _.isBoolean(false);
11409      * // => true
11410      *
11411      * _.isBoolean(null);
11412      * // => false
11413      */
11414     function isBoolean(value) {
11415       return value === true || value === false ||
11416         (isObjectLike(value) && baseGetTag(value) == boolTag);
11417     }
11418
11419     /**
11420      * Checks if `value` is a buffer.
11421      *
11422      * @static
11423      * @memberOf _
11424      * @since 4.3.0
11425      * @category Lang
11426      * @param {*} value The value to check.
11427      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
11428      * @example
11429      *
11430      * _.isBuffer(new Buffer(2));
11431      * // => true
11432      *
11433      * _.isBuffer(new Uint8Array(2));
11434      * // => false
11435      */
11436     var isBuffer = nativeIsBuffer || stubFalse;
11437
11438     /**
11439      * Checks if `value` is classified as a `Date` object.
11440      *
11441      * @static
11442      * @memberOf _
11443      * @since 0.1.0
11444      * @category Lang
11445      * @param {*} value The value to check.
11446      * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
11447      * @example
11448      *
11449      * _.isDate(new Date);
11450      * // => true
11451      *
11452      * _.isDate('Mon April 23 2012');
11453      * // => false
11454      */
11455     var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
11456
11457     /**
11458      * Checks if `value` is likely a DOM element.
11459      *
11460      * @static
11461      * @memberOf _
11462      * @since 0.1.0
11463      * @category Lang
11464      * @param {*} value The value to check.
11465      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
11466      * @example
11467      *
11468      * _.isElement(document.body);
11469      * // => true
11470      *
11471      * _.isElement('<body>');
11472      * // => false
11473      */
11474     function isElement(value) {
11475       return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
11476     }
11477
11478     /**
11479      * Checks if `value` is an empty object, collection, map, or set.
11480      *
11481      * Objects are considered empty if they have no own enumerable string keyed
11482      * properties.
11483      *
11484      * Array-like values such as `arguments` objects, arrays, buffers, strings, or
11485      * jQuery-like collections are considered empty if they have a `length` of `0`.
11486      * Similarly, maps and sets are considered empty if they have a `size` of `0`.
11487      *
11488      * @static
11489      * @memberOf _
11490      * @since 0.1.0
11491      * @category Lang
11492      * @param {*} value The value to check.
11493      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
11494      * @example
11495      *
11496      * _.isEmpty(null);
11497      * // => true
11498      *
11499      * _.isEmpty(true);
11500      * // => true
11501      *
11502      * _.isEmpty(1);
11503      * // => true
11504      *
11505      * _.isEmpty([1, 2, 3]);
11506      * // => false
11507      *
11508      * _.isEmpty({ 'a': 1 });
11509      * // => false
11510      */
11511     function isEmpty(value) {
11512       if (value == null) {
11513         return true;
11514       }
11515       if (isArrayLike(value) &&
11516           (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
11517             isBuffer(value) || isTypedArray(value) || isArguments(value))) {
11518         return !value.length;
11519       }
11520       var tag = getTag(value);
11521       if (tag == mapTag || tag == setTag) {
11522         return !value.size;
11523       }
11524       if (isPrototype(value)) {
11525         return !baseKeys(value).length;
11526       }
11527       for (var key in value) {
11528         if (hasOwnProperty.call(value, key)) {
11529           return false;
11530         }
11531       }
11532       return true;
11533     }
11534
11535     /**
11536      * Performs a deep comparison between two values to determine if they are
11537      * equivalent.
11538      *
11539      * **Note:** This method supports comparing arrays, array buffers, booleans,
11540      * date objects, error objects, maps, numbers, `Object` objects, regexes,
11541      * sets, strings, symbols, and typed arrays. `Object` objects are compared
11542      * by their own, not inherited, enumerable properties. Functions and DOM
11543      * nodes are compared by strict equality, i.e. `===`.
11544      *
11545      * @static
11546      * @memberOf _
11547      * @since 0.1.0
11548      * @category Lang
11549      * @param {*} value The value to compare.
11550      * @param {*} other The other value to compare.
11551      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11552      * @example
11553      *
11554      * var object = { 'a': 1 };
11555      * var other = { 'a': 1 };
11556      *
11557      * _.isEqual(object, other);
11558      * // => true
11559      *
11560      * object === other;
11561      * // => false
11562      */
11563     function isEqual(value, other) {
11564       return baseIsEqual(value, other);
11565     }
11566
11567     /**
11568      * This method is like `_.isEqual` except that it accepts `customizer` which
11569      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11570      * are handled by the method instead. The `customizer` is invoked with up to
11571      * six arguments: (objValue, othValue [, index|key, object, other, stack]).
11572      *
11573      * @static
11574      * @memberOf _
11575      * @since 4.0.0
11576      * @category Lang
11577      * @param {*} value The value to compare.
11578      * @param {*} other The other value to compare.
11579      * @param {Function} [customizer] The function to customize comparisons.
11580      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11581      * @example
11582      *
11583      * function isGreeting(value) {
11584      *   return /^h(?:i|ello)$/.test(value);
11585      * }
11586      *
11587      * function customizer(objValue, othValue) {
11588      *   if (isGreeting(objValue) && isGreeting(othValue)) {
11589      *     return true;
11590      *   }
11591      * }
11592      *
11593      * var array = ['hello', 'goodbye'];
11594      * var other = ['hi', 'goodbye'];
11595      *
11596      * _.isEqualWith(array, other, customizer);
11597      * // => true
11598      */
11599     function isEqualWith(value, other, customizer) {
11600       customizer = typeof customizer == 'function' ? customizer : undefined;
11601       var result = customizer ? customizer(value, other) : undefined;
11602       return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
11603     }
11604
11605     /**
11606      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
11607      * `SyntaxError`, `TypeError`, or `URIError` object.
11608      *
11609      * @static
11610      * @memberOf _
11611      * @since 3.0.0
11612      * @category Lang
11613      * @param {*} value The value to check.
11614      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
11615      * @example
11616      *
11617      * _.isError(new Error);
11618      * // => true
11619      *
11620      * _.isError(Error);
11621      * // => false
11622      */
11623     function isError(value) {
11624       if (!isObjectLike(value)) {
11625         return false;
11626       }
11627       var tag = baseGetTag(value);
11628       return tag == errorTag || tag == domExcTag ||
11629         (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
11630     }
11631
11632     /**
11633      * Checks if `value` is a finite primitive number.
11634      *
11635      * **Note:** This method is based on
11636      * [`Number.isFinite`](https://mdn.io/Number/isFinite).
11637      *
11638      * @static
11639      * @memberOf _
11640      * @since 0.1.0
11641      * @category Lang
11642      * @param {*} value The value to check.
11643      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
11644      * @example
11645      *
11646      * _.isFinite(3);
11647      * // => true
11648      *
11649      * _.isFinite(Number.MIN_VALUE);
11650      * // => true
11651      *
11652      * _.isFinite(Infinity);
11653      * // => false
11654      *
11655      * _.isFinite('3');
11656      * // => false
11657      */
11658     function isFinite(value) {
11659       return typeof value == 'number' && nativeIsFinite(value);
11660     }
11661
11662     /**
11663      * Checks if `value` is classified as a `Function` object.
11664      *
11665      * @static
11666      * @memberOf _
11667      * @since 0.1.0
11668      * @category Lang
11669      * @param {*} value The value to check.
11670      * @returns {boolean} Returns `true` if `value` is a function, else `false`.
11671      * @example
11672      *
11673      * _.isFunction(_);
11674      * // => true
11675      *
11676      * _.isFunction(/abc/);
11677      * // => false
11678      */
11679     function isFunction(value) {
11680       if (!isObject(value)) {
11681         return false;
11682       }
11683       // The use of `Object#toString` avoids issues with the `typeof` operator
11684       // in Safari 9 which returns 'object' for typed arrays and other constructors.
11685       var tag = baseGetTag(value);
11686       return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
11687     }
11688
11689     /**
11690      * Checks if `value` is an integer.
11691      *
11692      * **Note:** This method is based on
11693      * [`Number.isInteger`](https://mdn.io/Number/isInteger).
11694      *
11695      * @static
11696      * @memberOf _
11697      * @since 4.0.0
11698      * @category Lang
11699      * @param {*} value The value to check.
11700      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
11701      * @example
11702      *
11703      * _.isInteger(3);
11704      * // => true
11705      *
11706      * _.isInteger(Number.MIN_VALUE);
11707      * // => false
11708      *
11709      * _.isInteger(Infinity);
11710      * // => false
11711      *
11712      * _.isInteger('3');
11713      * // => false
11714      */
11715     function isInteger(value) {
11716       return typeof value == 'number' && value == toInteger(value);
11717     }
11718
11719     /**
11720      * Checks if `value` is a valid array-like length.
11721      *
11722      * **Note:** This method is loosely based on
11723      * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
11724      *
11725      * @static
11726      * @memberOf _
11727      * @since 4.0.0
11728      * @category Lang
11729      * @param {*} value The value to check.
11730      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
11731      * @example
11732      *
11733      * _.isLength(3);
11734      * // => true
11735      *
11736      * _.isLength(Number.MIN_VALUE);
11737      * // => false
11738      *
11739      * _.isLength(Infinity);
11740      * // => false
11741      *
11742      * _.isLength('3');
11743      * // => false
11744      */
11745     function isLength(value) {
11746       return typeof value == 'number' &&
11747         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11748     }
11749
11750     /**
11751      * Checks if `value` is the
11752      * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
11753      * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11754      *
11755      * @static
11756      * @memberOf _
11757      * @since 0.1.0
11758      * @category Lang
11759      * @param {*} value The value to check.
11760      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11761      * @example
11762      *
11763      * _.isObject({});
11764      * // => true
11765      *
11766      * _.isObject([1, 2, 3]);
11767      * // => true
11768      *
11769      * _.isObject(_.noop);
11770      * // => true
11771      *
11772      * _.isObject(null);
11773      * // => false
11774      */
11775     function isObject(value) {
11776       var type = typeof value;
11777       return value != null && (type == 'object' || type == 'function');
11778     }
11779
11780     /**
11781      * Checks if `value` is object-like. A value is object-like if it's not `null`
11782      * and has a `typeof` result of "object".
11783      *
11784      * @static
11785      * @memberOf _
11786      * @since 4.0.0
11787      * @category Lang
11788      * @param {*} value The value to check.
11789      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11790      * @example
11791      *
11792      * _.isObjectLike({});
11793      * // => true
11794      *
11795      * _.isObjectLike([1, 2, 3]);
11796      * // => true
11797      *
11798      * _.isObjectLike(_.noop);
11799      * // => false
11800      *
11801      * _.isObjectLike(null);
11802      * // => false
11803      */
11804     function isObjectLike(value) {
11805       return value != null && typeof value == 'object';
11806     }
11807
11808     /**
11809      * Checks if `value` is classified as a `Map` object.
11810      *
11811      * @static
11812      * @memberOf _
11813      * @since 4.3.0
11814      * @category Lang
11815      * @param {*} value The value to check.
11816      * @returns {boolean} Returns `true` if `value` is a map, else `false`.
11817      * @example
11818      *
11819      * _.isMap(new Map);
11820      * // => true
11821      *
11822      * _.isMap(new WeakMap);
11823      * // => false
11824      */
11825     var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
11826
11827     /**
11828      * Performs a partial deep comparison between `object` and `source` to
11829      * determine if `object` contains equivalent property values.
11830      *
11831      * **Note:** This method is equivalent to `_.matches` when `source` is
11832      * partially applied.
11833      *
11834      * Partial comparisons will match empty array and empty object `source`
11835      * values against any array or object value, respectively. See `_.isEqual`
11836      * for a list of supported value comparisons.
11837      *
11838      * @static
11839      * @memberOf _
11840      * @since 3.0.0
11841      * @category Lang
11842      * @param {Object} object The object to inspect.
11843      * @param {Object} source The object of property values to match.
11844      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11845      * @example
11846      *
11847      * var object = { 'a': 1, 'b': 2 };
11848      *
11849      * _.isMatch(object, { 'b': 2 });
11850      * // => true
11851      *
11852      * _.isMatch(object, { 'b': 1 });
11853      * // => false
11854      */
11855     function isMatch(object, source) {
11856       return object === source || baseIsMatch(object, source, getMatchData(source));
11857     }
11858
11859     /**
11860      * This method is like `_.isMatch` except that it accepts `customizer` which
11861      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11862      * are handled by the method instead. The `customizer` is invoked with five
11863      * arguments: (objValue, srcValue, index|key, object, source).
11864      *
11865      * @static
11866      * @memberOf _
11867      * @since 4.0.0
11868      * @category Lang
11869      * @param {Object} object The object to inspect.
11870      * @param {Object} source The object of property values to match.
11871      * @param {Function} [customizer] The function to customize comparisons.
11872      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11873      * @example
11874      *
11875      * function isGreeting(value) {
11876      *   return /^h(?:i|ello)$/.test(value);
11877      * }
11878      *
11879      * function customizer(objValue, srcValue) {
11880      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
11881      *     return true;
11882      *   }
11883      * }
11884      *
11885      * var object = { 'greeting': 'hello' };
11886      * var source = { 'greeting': 'hi' };
11887      *
11888      * _.isMatchWith(object, source, customizer);
11889      * // => true
11890      */
11891     function isMatchWith(object, source, customizer) {
11892       customizer = typeof customizer == 'function' ? customizer : undefined;
11893       return baseIsMatch(object, source, getMatchData(source), customizer);
11894     }
11895
11896     /**
11897      * Checks if `value` is `NaN`.
11898      *
11899      * **Note:** This method is based on
11900      * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11901      * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11902      * `undefined` and other non-number values.
11903      *
11904      * @static
11905      * @memberOf _
11906      * @since 0.1.0
11907      * @category Lang
11908      * @param {*} value The value to check.
11909      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11910      * @example
11911      *
11912      * _.isNaN(NaN);
11913      * // => true
11914      *
11915      * _.isNaN(new Number(NaN));
11916      * // => true
11917      *
11918      * isNaN(undefined);
11919      * // => true
11920      *
11921      * _.isNaN(undefined);
11922      * // => false
11923      */
11924     function isNaN(value) {
11925       // An `NaN` primitive is the only value that is not equal to itself.
11926       // Perform the `toStringTag` check first to avoid errors with some
11927       // ActiveX objects in IE.
11928       return isNumber(value) && value != +value;
11929     }
11930
11931     /**
11932      * Checks if `value` is a pristine native function.
11933      *
11934      * **Note:** This method can't reliably detect native functions in the presence
11935      * of the core-js package because core-js circumvents this kind of detection.
11936      * Despite multiple requests, the core-js maintainer has made it clear: any
11937      * attempt to fix the detection will be obstructed. As a result, we're left
11938      * with little choice but to throw an error. Unfortunately, this also affects
11939      * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11940      * which rely on core-js.
11941      *
11942      * @static
11943      * @memberOf _
11944      * @since 3.0.0
11945      * @category Lang
11946      * @param {*} value The value to check.
11947      * @returns {boolean} Returns `true` if `value` is a native function,
11948      *  else `false`.
11949      * @example
11950      *
11951      * _.isNative(Array.prototype.push);
11952      * // => true
11953      *
11954      * _.isNative(_);
11955      * // => false
11956      */
11957     function isNative(value) {
11958       if (isMaskable(value)) {
11959         throw new Error(CORE_ERROR_TEXT);
11960       }
11961       return baseIsNative(value);
11962     }
11963
11964     /**
11965      * Checks if `value` is `null`.
11966      *
11967      * @static
11968      * @memberOf _
11969      * @since 0.1.0
11970      * @category Lang
11971      * @param {*} value The value to check.
11972      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11973      * @example
11974      *
11975      * _.isNull(null);
11976      * // => true
11977      *
11978      * _.isNull(void 0);
11979      * // => false
11980      */
11981     function isNull(value) {
11982       return value === null;
11983     }
11984
11985     /**
11986      * Checks if `value` is `null` or `undefined`.
11987      *
11988      * @static
11989      * @memberOf _
11990      * @since 4.0.0
11991      * @category Lang
11992      * @param {*} value The value to check.
11993      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
11994      * @example
11995      *
11996      * _.isNil(null);
11997      * // => true
11998      *
11999      * _.isNil(void 0);
12000      * // => true
12001      *
12002      * _.isNil(NaN);
12003      * // => false
12004      */
12005     function isNil(value) {
12006       return value == null;
12007     }
12008
12009     /**
12010      * Checks if `value` is classified as a `Number` primitive or object.
12011      *
12012      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
12013      * classified as numbers, use the `_.isFinite` method.
12014      *
12015      * @static
12016      * @memberOf _
12017      * @since 0.1.0
12018      * @category Lang
12019      * @param {*} value The value to check.
12020      * @returns {boolean} Returns `true` if `value` is a number, else `false`.
12021      * @example
12022      *
12023      * _.isNumber(3);
12024      * // => true
12025      *
12026      * _.isNumber(Number.MIN_VALUE);
12027      * // => true
12028      *
12029      * _.isNumber(Infinity);
12030      * // => true
12031      *
12032      * _.isNumber('3');
12033      * // => false
12034      */
12035     function isNumber(value) {
12036       return typeof value == 'number' ||
12037         (isObjectLike(value) && baseGetTag(value) == numberTag);
12038     }
12039
12040     /**
12041      * Checks if `value` is a plain object, that is, an object created by the
12042      * `Object` constructor or one with a `[[Prototype]]` of `null`.
12043      *
12044      * @static
12045      * @memberOf _
12046      * @since 0.8.0
12047      * @category Lang
12048      * @param {*} value The value to check.
12049      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
12050      * @example
12051      *
12052      * function Foo() {
12053      *   this.a = 1;
12054      * }
12055      *
12056      * _.isPlainObject(new Foo);
12057      * // => false
12058      *
12059      * _.isPlainObject([1, 2, 3]);
12060      * // => false
12061      *
12062      * _.isPlainObject({ 'x': 0, 'y': 0 });
12063      * // => true
12064      *
12065      * _.isPlainObject(Object.create(null));
12066      * // => true
12067      */
12068     function isPlainObject(value) {
12069       if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
12070         return false;
12071       }
12072       var proto = getPrototype(value);
12073       if (proto === null) {
12074         return true;
12075       }
12076       var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
12077       return typeof Ctor == 'function' && Ctor instanceof Ctor &&
12078         funcToString.call(Ctor) == objectCtorString;
12079     }
12080
12081     /**
12082      * Checks if `value` is classified as a `RegExp` object.
12083      *
12084      * @static
12085      * @memberOf _
12086      * @since 0.1.0
12087      * @category Lang
12088      * @param {*} value The value to check.
12089      * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
12090      * @example
12091      *
12092      * _.isRegExp(/abc/);
12093      * // => true
12094      *
12095      * _.isRegExp('/abc/');
12096      * // => false
12097      */
12098     var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
12099
12100     /**
12101      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
12102      * double precision number which isn't the result of a rounded unsafe integer.
12103      *
12104      * **Note:** This method is based on
12105      * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
12106      *
12107      * @static
12108      * @memberOf _
12109      * @since 4.0.0
12110      * @category Lang
12111      * @param {*} value The value to check.
12112      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
12113      * @example
12114      *
12115      * _.isSafeInteger(3);
12116      * // => true
12117      *
12118      * _.isSafeInteger(Number.MIN_VALUE);
12119      * // => false
12120      *
12121      * _.isSafeInteger(Infinity);
12122      * // => false
12123      *
12124      * _.isSafeInteger('3');
12125      * // => false
12126      */
12127     function isSafeInteger(value) {
12128       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
12129     }
12130
12131     /**
12132      * Checks if `value` is classified as a `Set` object.
12133      *
12134      * @static
12135      * @memberOf _
12136      * @since 4.3.0
12137      * @category Lang
12138      * @param {*} value The value to check.
12139      * @returns {boolean} Returns `true` if `value` is a set, else `false`.
12140      * @example
12141      *
12142      * _.isSet(new Set);
12143      * // => true
12144      *
12145      * _.isSet(new WeakSet);
12146      * // => false
12147      */
12148     var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
12149
12150     /**
12151      * Checks if `value` is classified as a `String` primitive or object.
12152      *
12153      * @static
12154      * @since 0.1.0
12155      * @memberOf _
12156      * @category Lang
12157      * @param {*} value The value to check.
12158      * @returns {boolean} Returns `true` if `value` is a string, else `false`.
12159      * @example
12160      *
12161      * _.isString('abc');
12162      * // => true
12163      *
12164      * _.isString(1);
12165      * // => false
12166      */
12167     function isString(value) {
12168       return typeof value == 'string' ||
12169         (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
12170     }
12171
12172     /**
12173      * Checks if `value` is classified as a `Symbol` primitive or object.
12174      *
12175      * @static
12176      * @memberOf _
12177      * @since 4.0.0
12178      * @category Lang
12179      * @param {*} value The value to check.
12180      * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
12181      * @example
12182      *
12183      * _.isSymbol(Symbol.iterator);
12184      * // => true
12185      *
12186      * _.isSymbol('abc');
12187      * // => false
12188      */
12189     function isSymbol(value) {
12190       return typeof value == 'symbol' ||
12191         (isObjectLike(value) && baseGetTag(value) == symbolTag);
12192     }
12193
12194     /**
12195      * Checks if `value` is classified as a typed array.
12196      *
12197      * @static
12198      * @memberOf _
12199      * @since 3.0.0
12200      * @category Lang
12201      * @param {*} value The value to check.
12202      * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
12203      * @example
12204      *
12205      * _.isTypedArray(new Uint8Array);
12206      * // => true
12207      *
12208      * _.isTypedArray([]);
12209      * // => false
12210      */
12211     var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
12212
12213     /**
12214      * Checks if `value` is `undefined`.
12215      *
12216      * @static
12217      * @since 0.1.0
12218      * @memberOf _
12219      * @category Lang
12220      * @param {*} value The value to check.
12221      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
12222      * @example
12223      *
12224      * _.isUndefined(void 0);
12225      * // => true
12226      *
12227      * _.isUndefined(null);
12228      * // => false
12229      */
12230     function isUndefined(value) {
12231       return value === undefined;
12232     }
12233
12234     /**
12235      * Checks if `value` is classified as a `WeakMap` object.
12236      *
12237      * @static
12238      * @memberOf _
12239      * @since 4.3.0
12240      * @category Lang
12241      * @param {*} value The value to check.
12242      * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
12243      * @example
12244      *
12245      * _.isWeakMap(new WeakMap);
12246      * // => true
12247      *
12248      * _.isWeakMap(new Map);
12249      * // => false
12250      */
12251     function isWeakMap(value) {
12252       return isObjectLike(value) && getTag(value) == weakMapTag;
12253     }
12254
12255     /**
12256      * Checks if `value` is classified as a `WeakSet` object.
12257      *
12258      * @static
12259      * @memberOf _
12260      * @since 4.3.0
12261      * @category Lang
12262      * @param {*} value The value to check.
12263      * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
12264      * @example
12265      *
12266      * _.isWeakSet(new WeakSet);
12267      * // => true
12268      *
12269      * _.isWeakSet(new Set);
12270      * // => false
12271      */
12272     function isWeakSet(value) {
12273       return isObjectLike(value) && baseGetTag(value) == weakSetTag;
12274     }
12275
12276     /**
12277      * Checks if `value` is less than `other`.
12278      *
12279      * @static
12280      * @memberOf _
12281      * @since 3.9.0
12282      * @category Lang
12283      * @param {*} value The value to compare.
12284      * @param {*} other The other value to compare.
12285      * @returns {boolean} Returns `true` if `value` is less than `other`,
12286      *  else `false`.
12287      * @see _.gt
12288      * @example
12289      *
12290      * _.lt(1, 3);
12291      * // => true
12292      *
12293      * _.lt(3, 3);
12294      * // => false
12295      *
12296      * _.lt(3, 1);
12297      * // => false
12298      */
12299     var lt = createRelationalOperation(baseLt);
12300
12301     /**
12302      * Checks if `value` is less than or equal to `other`.
12303      *
12304      * @static
12305      * @memberOf _
12306      * @since 3.9.0
12307      * @category Lang
12308      * @param {*} value The value to compare.
12309      * @param {*} other The other value to compare.
12310      * @returns {boolean} Returns `true` if `value` is less than or equal to
12311      *  `other`, else `false`.
12312      * @see _.gte
12313      * @example
12314      *
12315      * _.lte(1, 3);
12316      * // => true
12317      *
12318      * _.lte(3, 3);
12319      * // => true
12320      *
12321      * _.lte(3, 1);
12322      * // => false
12323      */
12324     var lte = createRelationalOperation(function(value, other) {
12325       return value <= other;
12326     });
12327
12328     /**
12329      * Converts `value` to an array.
12330      *
12331      * @static
12332      * @since 0.1.0
12333      * @memberOf _
12334      * @category Lang
12335      * @param {*} value The value to convert.
12336      * @returns {Array} Returns the converted array.
12337      * @example
12338      *
12339      * _.toArray({ 'a': 1, 'b': 2 });
12340      * // => [1, 2]
12341      *
12342      * _.toArray('abc');
12343      * // => ['a', 'b', 'c']
12344      *
12345      * _.toArray(1);
12346      * // => []
12347      *
12348      * _.toArray(null);
12349      * // => []
12350      */
12351     function toArray(value) {
12352       if (!value) {
12353         return [];
12354       }
12355       if (isArrayLike(value)) {
12356         return isString(value) ? stringToArray(value) : copyArray(value);
12357       }
12358       if (symIterator && value[symIterator]) {
12359         return iteratorToArray(value[symIterator]());
12360       }
12361       var tag = getTag(value),
12362           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
12363
12364       return func(value);
12365     }
12366
12367     /**
12368      * Converts `value` to a finite number.
12369      *
12370      * @static
12371      * @memberOf _
12372      * @since 4.12.0
12373      * @category Lang
12374      * @param {*} value The value to convert.
12375      * @returns {number} Returns the converted number.
12376      * @example
12377      *
12378      * _.toFinite(3.2);
12379      * // => 3.2
12380      *
12381      * _.toFinite(Number.MIN_VALUE);
12382      * // => 5e-324
12383      *
12384      * _.toFinite(Infinity);
12385      * // => 1.7976931348623157e+308
12386      *
12387      * _.toFinite('3.2');
12388      * // => 3.2
12389      */
12390     function toFinite(value) {
12391       if (!value) {
12392         return value === 0 ? value : 0;
12393       }
12394       value = toNumber(value);
12395       if (value === INFINITY || value === -INFINITY) {
12396         var sign = (value < 0 ? -1 : 1);
12397         return sign * MAX_INTEGER;
12398       }
12399       return value === value ? value : 0;
12400     }
12401
12402     /**
12403      * Converts `value` to an integer.
12404      *
12405      * **Note:** This method is loosely based on
12406      * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
12407      *
12408      * @static
12409      * @memberOf _
12410      * @since 4.0.0
12411      * @category Lang
12412      * @param {*} value The value to convert.
12413      * @returns {number} Returns the converted integer.
12414      * @example
12415      *
12416      * _.toInteger(3.2);
12417      * // => 3
12418      *
12419      * _.toInteger(Number.MIN_VALUE);
12420      * // => 0
12421      *
12422      * _.toInteger(Infinity);
12423      * // => 1.7976931348623157e+308
12424      *
12425      * _.toInteger('3.2');
12426      * // => 3
12427      */
12428     function toInteger(value) {
12429       var result = toFinite(value),
12430           remainder = result % 1;
12431
12432       return result === result ? (remainder ? result - remainder : result) : 0;
12433     }
12434
12435     /**
12436      * Converts `value` to an integer suitable for use as the length of an
12437      * array-like object.
12438      *
12439      * **Note:** This method is based on
12440      * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12441      *
12442      * @static
12443      * @memberOf _
12444      * @since 4.0.0
12445      * @category Lang
12446      * @param {*} value The value to convert.
12447      * @returns {number} Returns the converted integer.
12448      * @example
12449      *
12450      * _.toLength(3.2);
12451      * // => 3
12452      *
12453      * _.toLength(Number.MIN_VALUE);
12454      * // => 0
12455      *
12456      * _.toLength(Infinity);
12457      * // => 4294967295
12458      *
12459      * _.toLength('3.2');
12460      * // => 3
12461      */
12462     function toLength(value) {
12463       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
12464     }
12465
12466     /**
12467      * Converts `value` to a number.
12468      *
12469      * @static
12470      * @memberOf _
12471      * @since 4.0.0
12472      * @category Lang
12473      * @param {*} value The value to process.
12474      * @returns {number} Returns the number.
12475      * @example
12476      *
12477      * _.toNumber(3.2);
12478      * // => 3.2
12479      *
12480      * _.toNumber(Number.MIN_VALUE);
12481      * // => 5e-324
12482      *
12483      * _.toNumber(Infinity);
12484      * // => Infinity
12485      *
12486      * _.toNumber('3.2');
12487      * // => 3.2
12488      */
12489     function toNumber(value) {
12490       if (typeof value == 'number') {
12491         return value;
12492       }
12493       if (isSymbol(value)) {
12494         return NAN;
12495       }
12496       if (isObject(value)) {
12497         var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
12498         value = isObject(other) ? (other + '') : other;
12499       }
12500       if (typeof value != 'string') {
12501         return value === 0 ? value : +value;
12502       }
12503       value = value.replace(reTrim, '');
12504       var isBinary = reIsBinary.test(value);
12505       return (isBinary || reIsOctal.test(value))
12506         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
12507         : (reIsBadHex.test(value) ? NAN : +value);
12508     }
12509
12510     /**
12511      * Converts `value` to a plain object flattening inherited enumerable string
12512      * keyed properties of `value` to own properties of the plain object.
12513      *
12514      * @static
12515      * @memberOf _
12516      * @since 3.0.0
12517      * @category Lang
12518      * @param {*} value The value to convert.
12519      * @returns {Object} Returns the converted plain object.
12520      * @example
12521      *
12522      * function Foo() {
12523      *   this.b = 2;
12524      * }
12525      *
12526      * Foo.prototype.c = 3;
12527      *
12528      * _.assign({ 'a': 1 }, new Foo);
12529      * // => { 'a': 1, 'b': 2 }
12530      *
12531      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
12532      * // => { 'a': 1, 'b': 2, 'c': 3 }
12533      */
12534     function toPlainObject(value) {
12535       return copyObject(value, keysIn(value));
12536     }
12537
12538     /**
12539      * Converts `value` to a safe integer. A safe integer can be compared and
12540      * represented correctly.
12541      *
12542      * @static
12543      * @memberOf _
12544      * @since 4.0.0
12545      * @category Lang
12546      * @param {*} value The value to convert.
12547      * @returns {number} Returns the converted integer.
12548      * @example
12549      *
12550      * _.toSafeInteger(3.2);
12551      * // => 3
12552      *
12553      * _.toSafeInteger(Number.MIN_VALUE);
12554      * // => 0
12555      *
12556      * _.toSafeInteger(Infinity);
12557      * // => 9007199254740991
12558      *
12559      * _.toSafeInteger('3.2');
12560      * // => 3
12561      */
12562     function toSafeInteger(value) {
12563       return value
12564         ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
12565         : (value === 0 ? value : 0);
12566     }
12567
12568     /**
12569      * Converts `value` to a string. An empty string is returned for `null`
12570      * and `undefined` values. The sign of `-0` is preserved.
12571      *
12572      * @static
12573      * @memberOf _
12574      * @since 4.0.0
12575      * @category Lang
12576      * @param {*} value The value to convert.
12577      * @returns {string} Returns the converted string.
12578      * @example
12579      *
12580      * _.toString(null);
12581      * // => ''
12582      *
12583      * _.toString(-0);
12584      * // => '-0'
12585      *
12586      * _.toString([1, 2, 3]);
12587      * // => '1,2,3'
12588      */
12589     function toString(value) {
12590       return value == null ? '' : baseToString(value);
12591     }
12592
12593     /*------------------------------------------------------------------------*/
12594
12595     /**
12596      * Assigns own enumerable string keyed properties of source objects to the
12597      * destination object. Source objects are applied from left to right.
12598      * Subsequent sources overwrite property assignments of previous sources.
12599      *
12600      * **Note:** This method mutates `object` and is loosely based on
12601      * [`Object.assign`](https://mdn.io/Object/assign).
12602      *
12603      * @static
12604      * @memberOf _
12605      * @since 0.10.0
12606      * @category Object
12607      * @param {Object} object The destination object.
12608      * @param {...Object} [sources] The source objects.
12609      * @returns {Object} Returns `object`.
12610      * @see _.assignIn
12611      * @example
12612      *
12613      * function Foo() {
12614      *   this.a = 1;
12615      * }
12616      *
12617      * function Bar() {
12618      *   this.c = 3;
12619      * }
12620      *
12621      * Foo.prototype.b = 2;
12622      * Bar.prototype.d = 4;
12623      *
12624      * _.assign({ 'a': 0 }, new Foo, new Bar);
12625      * // => { 'a': 1, 'c': 3 }
12626      */
12627     var assign = createAssigner(function(object, source) {
12628       if (isPrototype(source) || isArrayLike(source)) {
12629         copyObject(source, keys(source), object);
12630         return;
12631       }
12632       for (var key in source) {
12633         if (hasOwnProperty.call(source, key)) {
12634           assignValue(object, key, source[key]);
12635         }
12636       }
12637     });
12638
12639     /**
12640      * This method is like `_.assign` except that it iterates over own and
12641      * inherited source properties.
12642      *
12643      * **Note:** This method mutates `object`.
12644      *
12645      * @static
12646      * @memberOf _
12647      * @since 4.0.0
12648      * @alias extend
12649      * @category Object
12650      * @param {Object} object The destination object.
12651      * @param {...Object} [sources] The source objects.
12652      * @returns {Object} Returns `object`.
12653      * @see _.assign
12654      * @example
12655      *
12656      * function Foo() {
12657      *   this.a = 1;
12658      * }
12659      *
12660      * function Bar() {
12661      *   this.c = 3;
12662      * }
12663      *
12664      * Foo.prototype.b = 2;
12665      * Bar.prototype.d = 4;
12666      *
12667      * _.assignIn({ 'a': 0 }, new Foo, new Bar);
12668      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
12669      */
12670     var assignIn = createAssigner(function(object, source) {
12671       copyObject(source, keysIn(source), object);
12672     });
12673
12674     /**
12675      * This method is like `_.assignIn` except that it accepts `customizer`
12676      * which is invoked to produce the assigned values. If `customizer` returns
12677      * `undefined`, assignment is handled by the method instead. The `customizer`
12678      * is invoked with five arguments: (objValue, srcValue, key, object, source).
12679      *
12680      * **Note:** This method mutates `object`.
12681      *
12682      * @static
12683      * @memberOf _
12684      * @since 4.0.0
12685      * @alias extendWith
12686      * @category Object
12687      * @param {Object} object The destination object.
12688      * @param {...Object} sources The source objects.
12689      * @param {Function} [customizer] The function to customize assigned values.
12690      * @returns {Object} Returns `object`.
12691      * @see _.assignWith
12692      * @example
12693      *
12694      * function customizer(objValue, srcValue) {
12695      *   return _.isUndefined(objValue) ? srcValue : objValue;
12696      * }
12697      *
12698      * var defaults = _.partialRight(_.assignInWith, customizer);
12699      *
12700      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12701      * // => { 'a': 1, 'b': 2 }
12702      */
12703     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12704       copyObject(source, keysIn(source), object, customizer);
12705     });
12706
12707     /**
12708      * This method is like `_.assign` except that it accepts `customizer`
12709      * which is invoked to produce the assigned values. If `customizer` returns
12710      * `undefined`, assignment is handled by the method instead. The `customizer`
12711      * is invoked with five arguments: (objValue, srcValue, key, object, source).
12712      *
12713      * **Note:** This method mutates `object`.
12714      *
12715      * @static
12716      * @memberOf _
12717      * @since 4.0.0
12718      * @category Object
12719      * @param {Object} object The destination object.
12720      * @param {...Object} sources The source objects.
12721      * @param {Function} [customizer] The function to customize assigned values.
12722      * @returns {Object} Returns `object`.
12723      * @see _.assignInWith
12724      * @example
12725      *
12726      * function customizer(objValue, srcValue) {
12727      *   return _.isUndefined(objValue) ? srcValue : objValue;
12728      * }
12729      *
12730      * var defaults = _.partialRight(_.assignWith, customizer);
12731      *
12732      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12733      * // => { 'a': 1, 'b': 2 }
12734      */
12735     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12736       copyObject(source, keys(source), object, customizer);
12737     });
12738
12739     /**
12740      * Creates an array of values corresponding to `paths` of `object`.
12741      *
12742      * @static
12743      * @memberOf _
12744      * @since 1.0.0
12745      * @category Object
12746      * @param {Object} object The object to iterate over.
12747      * @param {...(string|string[])} [paths] The property paths to pick.
12748      * @returns {Array} Returns the picked values.
12749      * @example
12750      *
12751      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12752      *
12753      * _.at(object, ['a[0].b.c', 'a[1]']);
12754      * // => [3, 4]
12755      */
12756     var at = flatRest(baseAt);
12757
12758     /**
12759      * Creates an object that inherits from the `prototype` object. If a
12760      * `properties` object is given, its own enumerable string keyed properties
12761      * are assigned to the created object.
12762      *
12763      * @static
12764      * @memberOf _
12765      * @since 2.3.0
12766      * @category Object
12767      * @param {Object} prototype The object to inherit from.
12768      * @param {Object} [properties] The properties to assign to the object.
12769      * @returns {Object} Returns the new object.
12770      * @example
12771      *
12772      * function Shape() {
12773      *   this.x = 0;
12774      *   this.y = 0;
12775      * }
12776      *
12777      * function Circle() {
12778      *   Shape.call(this);
12779      * }
12780      *
12781      * Circle.prototype = _.create(Shape.prototype, {
12782      *   'constructor': Circle
12783      * });
12784      *
12785      * var circle = new Circle;
12786      * circle instanceof Circle;
12787      * // => true
12788      *
12789      * circle instanceof Shape;
12790      * // => true
12791      */
12792     function create(prototype, properties) {
12793       var result = baseCreate(prototype);
12794       return properties == null ? result : baseAssign(result, properties);
12795     }
12796
12797     /**
12798      * Assigns own and inherited enumerable string keyed properties of source
12799      * objects to the destination object for all destination properties that
12800      * resolve to `undefined`. Source objects are applied from left to right.
12801      * Once a property is set, additional values of the same property are ignored.
12802      *
12803      * **Note:** This method mutates `object`.
12804      *
12805      * @static
12806      * @since 0.1.0
12807      * @memberOf _
12808      * @category Object
12809      * @param {Object} object The destination object.
12810      * @param {...Object} [sources] The source objects.
12811      * @returns {Object} Returns `object`.
12812      * @see _.defaultsDeep
12813      * @example
12814      *
12815      * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12816      * // => { 'a': 1, 'b': 2 }
12817      */
12818     var defaults = baseRest(function(args) {
12819       args.push(undefined, customDefaultsAssignIn);
12820       return apply(assignInWith, undefined, args);
12821     });
12822
12823     /**
12824      * This method is like `_.defaults` except that it recursively assigns
12825      * default properties.
12826      *
12827      * **Note:** This method mutates `object`.
12828      *
12829      * @static
12830      * @memberOf _
12831      * @since 3.10.0
12832      * @category Object
12833      * @param {Object} object The destination object.
12834      * @param {...Object} [sources] The source objects.
12835      * @returns {Object} Returns `object`.
12836      * @see _.defaults
12837      * @example
12838      *
12839      * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
12840      * // => { 'a': { 'b': 2, 'c': 3 } }
12841      */
12842     var defaultsDeep = baseRest(function(args) {
12843       args.push(undefined, customDefaultsMerge);
12844       return apply(mergeWith, undefined, args);
12845     });
12846
12847     /**
12848      * This method is like `_.find` except that it returns the key of the first
12849      * element `predicate` returns truthy for instead of the element itself.
12850      *
12851      * @static
12852      * @memberOf _
12853      * @since 1.1.0
12854      * @category Object
12855      * @param {Object} object The object to inspect.
12856      * @param {Function} [predicate=_.identity] The function invoked per iteration.
12857      * @returns {string|undefined} Returns the key of the matched element,
12858      *  else `undefined`.
12859      * @example
12860      *
12861      * var users = {
12862      *   'barney':  { 'age': 36, 'active': true },
12863      *   'fred':    { 'age': 40, 'active': false },
12864      *   'pebbles': { 'age': 1,  'active': true }
12865      * };
12866      *
12867      * _.findKey(users, function(o) { return o.age < 40; });
12868      * // => 'barney' (iteration order is not guaranteed)
12869      *
12870      * // The `_.matches` iteratee shorthand.
12871      * _.findKey(users, { 'age': 1, 'active': true });
12872      * // => 'pebbles'
12873      *
12874      * // The `_.matchesProperty` iteratee shorthand.
12875      * _.findKey(users, ['active', false]);
12876      * // => 'fred'
12877      *
12878      * // The `_.property` iteratee shorthand.
12879      * _.findKey(users, 'active');
12880      * // => 'barney'
12881      */
12882     function findKey(object, predicate) {
12883       return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12884     }
12885
12886     /**
12887      * This method is like `_.findKey` except that it iterates over elements of
12888      * a collection in the opposite order.
12889      *
12890      * @static
12891      * @memberOf _
12892      * @since 2.0.0
12893      * @category Object
12894      * @param {Object} object The object to inspect.
12895      * @param {Function} [predicate=_.identity] The function invoked per iteration.
12896      * @returns {string|undefined} Returns the key of the matched element,
12897      *  else `undefined`.
12898      * @example
12899      *
12900      * var users = {
12901      *   'barney':  { 'age': 36, 'active': true },
12902      *   'fred':    { 'age': 40, 'active': false },
12903      *   'pebbles': { 'age': 1,  'active': true }
12904      * };
12905      *
12906      * _.findLastKey(users, function(o) { return o.age < 40; });
12907      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12908      *
12909      * // The `_.matches` iteratee shorthand.
12910      * _.findLastKey(users, { 'age': 36, 'active': true });
12911      * // => 'barney'
12912      *
12913      * // The `_.matchesProperty` iteratee shorthand.
12914      * _.findLastKey(users, ['active', false]);
12915      * // => 'fred'
12916      *
12917      * // The `_.property` iteratee shorthand.
12918      * _.findLastKey(users, 'active');
12919      * // => 'pebbles'
12920      */
12921     function findLastKey(object, predicate) {
12922       return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12923     }
12924
12925     /**
12926      * Iterates over own and inherited enumerable string keyed properties of an
12927      * object and invokes `iteratee` for each property. The iteratee is invoked
12928      * with three arguments: (value, key, object). Iteratee functions may exit
12929      * iteration early by explicitly returning `false`.
12930      *
12931      * @static
12932      * @memberOf _
12933      * @since 0.3.0
12934      * @category Object
12935      * @param {Object} object The object to iterate over.
12936      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12937      * @returns {Object} Returns `object`.
12938      * @see _.forInRight
12939      * @example
12940      *
12941      * function Foo() {
12942      *   this.a = 1;
12943      *   this.b = 2;
12944      * }
12945      *
12946      * Foo.prototype.c = 3;
12947      *
12948      * _.forIn(new Foo, function(value, key) {
12949      *   console.log(key);
12950      * });
12951      * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12952      */
12953     function forIn(object, iteratee) {
12954       return object == null
12955         ? object
12956         : baseFor(object, getIteratee(iteratee, 3), keysIn);
12957     }
12958
12959     /**
12960      * This method is like `_.forIn` except that it iterates over properties of
12961      * `object` in the opposite order.
12962      *
12963      * @static
12964      * @memberOf _
12965      * @since 2.0.0
12966      * @category Object
12967      * @param {Object} object The object to iterate over.
12968      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12969      * @returns {Object} Returns `object`.
12970      * @see _.forIn
12971      * @example
12972      *
12973      * function Foo() {
12974      *   this.a = 1;
12975      *   this.b = 2;
12976      * }
12977      *
12978      * Foo.prototype.c = 3;
12979      *
12980      * _.forInRight(new Foo, function(value, key) {
12981      *   console.log(key);
12982      * });
12983      * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12984      */
12985     function forInRight(object, iteratee) {
12986       return object == null
12987         ? object
12988         : baseForRight(object, getIteratee(iteratee, 3), keysIn);
12989     }
12990
12991     /**
12992      * Iterates over own enumerable string keyed properties of an object and
12993      * invokes `iteratee` for each property. The iteratee is invoked with three
12994      * arguments: (value, key, object). Iteratee functions may exit iteration
12995      * early by explicitly returning `false`.
12996      *
12997      * @static
12998      * @memberOf _
12999      * @since 0.3.0
13000      * @category Object
13001      * @param {Object} object The object to iterate over.
13002      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13003      * @returns {Object} Returns `object`.
13004      * @see _.forOwnRight
13005      * @example
13006      *
13007      * function Foo() {
13008      *   this.a = 1;
13009      *   this.b = 2;
13010      * }
13011      *
13012      * Foo.prototype.c = 3;
13013      *
13014      * _.forOwn(new Foo, function(value, key) {
13015      *   console.log(key);
13016      * });
13017      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
13018      */
13019     function forOwn(object, iteratee) {
13020       return object && baseForOwn(object, getIteratee(iteratee, 3));
13021     }
13022
13023     /**
13024      * This method is like `_.forOwn` except that it iterates over properties of
13025      * `object` in the opposite order.
13026      *
13027      * @static
13028      * @memberOf _
13029      * @since 2.0.0
13030      * @category Object
13031      * @param {Object} object The object to iterate over.
13032      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13033      * @returns {Object} Returns `object`.
13034      * @see _.forOwn
13035      * @example
13036      *
13037      * function Foo() {
13038      *   this.a = 1;
13039      *   this.b = 2;
13040      * }
13041      *
13042      * Foo.prototype.c = 3;
13043      *
13044      * _.forOwnRight(new Foo, function(value, key) {
13045      *   console.log(key);
13046      * });
13047      * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
13048      */
13049     function forOwnRight(object, iteratee) {
13050       return object && baseForOwnRight(object, getIteratee(iteratee, 3));
13051     }
13052
13053     /**
13054      * Creates an array of function property names from own enumerable properties
13055      * of `object`.
13056      *
13057      * @static
13058      * @since 0.1.0
13059      * @memberOf _
13060      * @category Object
13061      * @param {Object} object The object to inspect.
13062      * @returns {Array} Returns the function names.
13063      * @see _.functionsIn
13064      * @example
13065      *
13066      * function Foo() {
13067      *   this.a = _.constant('a');
13068      *   this.b = _.constant('b');
13069      * }
13070      *
13071      * Foo.prototype.c = _.constant('c');
13072      *
13073      * _.functions(new Foo);
13074      * // => ['a', 'b']
13075      */
13076     function functions(object) {
13077       return object == null ? [] : baseFunctions(object, keys(object));
13078     }
13079
13080     /**
13081      * Creates an array of function property names from own and inherited
13082      * enumerable properties of `object`.
13083      *
13084      * @static
13085      * @memberOf _
13086      * @since 4.0.0
13087      * @category Object
13088      * @param {Object} object The object to inspect.
13089      * @returns {Array} Returns the function names.
13090      * @see _.functions
13091      * @example
13092      *
13093      * function Foo() {
13094      *   this.a = _.constant('a');
13095      *   this.b = _.constant('b');
13096      * }
13097      *
13098      * Foo.prototype.c = _.constant('c');
13099      *
13100      * _.functionsIn(new Foo);
13101      * // => ['a', 'b', 'c']
13102      */
13103     function functionsIn(object) {
13104       return object == null ? [] : baseFunctions(object, keysIn(object));
13105     }
13106
13107     /**
13108      * Gets the value at `path` of `object`. If the resolved value is
13109      * `undefined`, the `defaultValue` is returned in its place.
13110      *
13111      * @static
13112      * @memberOf _
13113      * @since 3.7.0
13114      * @category Object
13115      * @param {Object} object The object to query.
13116      * @param {Array|string} path The path of the property to get.
13117      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13118      * @returns {*} Returns the resolved value.
13119      * @example
13120      *
13121      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13122      *
13123      * _.get(object, 'a[0].b.c');
13124      * // => 3
13125      *
13126      * _.get(object, ['a', '0', 'b', 'c']);
13127      * // => 3
13128      *
13129      * _.get(object, 'a.b.c', 'default');
13130      * // => 'default'
13131      */
13132     function get(object, path, defaultValue) {
13133       var result = object == null ? undefined : baseGet(object, path);
13134       return result === undefined ? defaultValue : result;
13135     }
13136
13137     /**
13138      * Checks if `path` is a direct property of `object`.
13139      *
13140      * @static
13141      * @since 0.1.0
13142      * @memberOf _
13143      * @category Object
13144      * @param {Object} object The object to query.
13145      * @param {Array|string} path The path to check.
13146      * @returns {boolean} Returns `true` if `path` exists, else `false`.
13147      * @example
13148      *
13149      * var object = { 'a': { 'b': 2 } };
13150      * var other = _.create({ 'a': _.create({ 'b': 2 }) });
13151      *
13152      * _.has(object, 'a');
13153      * // => true
13154      *
13155      * _.has(object, 'a.b');
13156      * // => true
13157      *
13158      * _.has(object, ['a', 'b']);
13159      * // => true
13160      *
13161      * _.has(other, 'a');
13162      * // => false
13163      */
13164     function has(object, path) {
13165       return object != null && hasPath(object, path, baseHas);
13166     }
13167
13168     /**
13169      * Checks if `path` is a direct or inherited property of `object`.
13170      *
13171      * @static
13172      * @memberOf _
13173      * @since 4.0.0
13174      * @category Object
13175      * @param {Object} object The object to query.
13176      * @param {Array|string} path The path to check.
13177      * @returns {boolean} Returns `true` if `path` exists, else `false`.
13178      * @example
13179      *
13180      * var object = _.create({ 'a': _.create({ 'b': 2 }) });
13181      *
13182      * _.hasIn(object, 'a');
13183      * // => true
13184      *
13185      * _.hasIn(object, 'a.b');
13186      * // => true
13187      *
13188      * _.hasIn(object, ['a', 'b']);
13189      * // => true
13190      *
13191      * _.hasIn(object, 'b');
13192      * // => false
13193      */
13194     function hasIn(object, path) {
13195       return object != null && hasPath(object, path, baseHasIn);
13196     }
13197
13198     /**
13199      * Creates an object composed of the inverted keys and values of `object`.
13200      * If `object` contains duplicate values, subsequent values overwrite
13201      * property assignments of previous values.
13202      *
13203      * @static
13204      * @memberOf _
13205      * @since 0.7.0
13206      * @category Object
13207      * @param {Object} object The object to invert.
13208      * @returns {Object} Returns the new inverted object.
13209      * @example
13210      *
13211      * var object = { 'a': 1, 'b': 2, 'c': 1 };
13212      *
13213      * _.invert(object);
13214      * // => { '1': 'c', '2': 'b' }
13215      */
13216     var invert = createInverter(function(result, value, key) {
13217       result[value] = key;
13218     }, constant(identity));
13219
13220     /**
13221      * This method is like `_.invert` except that the inverted object is generated
13222      * from the results of running each element of `object` thru `iteratee`. The
13223      * corresponding inverted value of each inverted key is an array of keys
13224      * responsible for generating the inverted value. The iteratee is invoked
13225      * with one argument: (value).
13226      *
13227      * @static
13228      * @memberOf _
13229      * @since 4.1.0
13230      * @category Object
13231      * @param {Object} object The object to invert.
13232      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
13233      * @returns {Object} Returns the new inverted object.
13234      * @example
13235      *
13236      * var object = { 'a': 1, 'b': 2, 'c': 1 };
13237      *
13238      * _.invertBy(object);
13239      * // => { '1': ['a', 'c'], '2': ['b'] }
13240      *
13241      * _.invertBy(object, function(value) {
13242      *   return 'group' + value;
13243      * });
13244      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
13245      */
13246     var invertBy = createInverter(function(result, value, key) {
13247       if (hasOwnProperty.call(result, value)) {
13248         result[value].push(key);
13249       } else {
13250         result[value] = [key];
13251       }
13252     }, getIteratee);
13253
13254     /**
13255      * Invokes the method at `path` of `object`.
13256      *
13257      * @static
13258      * @memberOf _
13259      * @since 4.0.0
13260      * @category Object
13261      * @param {Object} object The object to query.
13262      * @param {Array|string} path The path of the method to invoke.
13263      * @param {...*} [args] The arguments to invoke the method with.
13264      * @returns {*} Returns the result of the invoked method.
13265      * @example
13266      *
13267      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
13268      *
13269      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
13270      * // => [2, 3]
13271      */
13272     var invoke = baseRest(baseInvoke);
13273
13274     /**
13275      * Creates an array of the own enumerable property names of `object`.
13276      *
13277      * **Note:** Non-object values are coerced to objects. See the
13278      * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13279      * for more details.
13280      *
13281      * @static
13282      * @since 0.1.0
13283      * @memberOf _
13284      * @category Object
13285      * @param {Object} object The object to query.
13286      * @returns {Array} Returns the array of property names.
13287      * @example
13288      *
13289      * function Foo() {
13290      *   this.a = 1;
13291      *   this.b = 2;
13292      * }
13293      *
13294      * Foo.prototype.c = 3;
13295      *
13296      * _.keys(new Foo);
13297      * // => ['a', 'b'] (iteration order is not guaranteed)
13298      *
13299      * _.keys('hi');
13300      * // => ['0', '1']
13301      */
13302     function keys(object) {
13303       return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
13304     }
13305
13306     /**
13307      * Creates an array of the own and inherited enumerable property names of `object`.
13308      *
13309      * **Note:** Non-object values are coerced to objects.
13310      *
13311      * @static
13312      * @memberOf _
13313      * @since 3.0.0
13314      * @category Object
13315      * @param {Object} object The object to query.
13316      * @returns {Array} Returns the array of property names.
13317      * @example
13318      *
13319      * function Foo() {
13320      *   this.a = 1;
13321      *   this.b = 2;
13322      * }
13323      *
13324      * Foo.prototype.c = 3;
13325      *
13326      * _.keysIn(new Foo);
13327      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
13328      */
13329     function keysIn(object) {
13330       return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
13331     }
13332
13333     /**
13334      * The opposite of `_.mapValues`; this method creates an object with the
13335      * same values as `object` and keys generated by running each own enumerable
13336      * string keyed property of `object` thru `iteratee`. The iteratee is invoked
13337      * with three arguments: (value, key, object).
13338      *
13339      * @static
13340      * @memberOf _
13341      * @since 3.8.0
13342      * @category Object
13343      * @param {Object} object The object to iterate over.
13344      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13345      * @returns {Object} Returns the new mapped object.
13346      * @see _.mapValues
13347      * @example
13348      *
13349      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
13350      *   return key + value;
13351      * });
13352      * // => { 'a1': 1, 'b2': 2 }
13353      */
13354     function mapKeys(object, iteratee) {
13355       var result = {};
13356       iteratee = getIteratee(iteratee, 3);
13357
13358       baseForOwn(object, function(value, key, object) {
13359         baseAssignValue(result, iteratee(value, key, object), value);
13360       });
13361       return result;
13362     }
13363
13364     /**
13365      * Creates an object with the same keys as `object` and values generated
13366      * by running each own enumerable string keyed property of `object` thru
13367      * `iteratee`. The iteratee is invoked with three arguments:
13368      * (value, key, object).
13369      *
13370      * @static
13371      * @memberOf _
13372      * @since 2.4.0
13373      * @category Object
13374      * @param {Object} object The object to iterate over.
13375      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13376      * @returns {Object} Returns the new mapped object.
13377      * @see _.mapKeys
13378      * @example
13379      *
13380      * var users = {
13381      *   'fred':    { 'user': 'fred',    'age': 40 },
13382      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
13383      * };
13384      *
13385      * _.mapValues(users, function(o) { return o.age; });
13386      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13387      *
13388      * // The `_.property` iteratee shorthand.
13389      * _.mapValues(users, 'age');
13390      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13391      */
13392     function mapValues(object, iteratee) {
13393       var result = {};
13394       iteratee = getIteratee(iteratee, 3);
13395
13396       baseForOwn(object, function(value, key, object) {
13397         baseAssignValue(result, key, iteratee(value, key, object));
13398       });
13399       return result;
13400     }
13401
13402     /**
13403      * This method is like `_.assign` except that it recursively merges own and
13404      * inherited enumerable string keyed properties of source objects into the
13405      * destination object. Source properties that resolve to `undefined` are
13406      * skipped if a destination value exists. Array and plain object properties
13407      * are merged recursively. Other objects and value types are overridden by
13408      * assignment. Source objects are applied from left to right. Subsequent
13409      * sources overwrite property assignments of previous sources.
13410      *
13411      * **Note:** This method mutates `object`.
13412      *
13413      * @static
13414      * @memberOf _
13415      * @since 0.5.0
13416      * @category Object
13417      * @param {Object} object The destination object.
13418      * @param {...Object} [sources] The source objects.
13419      * @returns {Object} Returns `object`.
13420      * @example
13421      *
13422      * var object = {
13423      *   'a': [{ 'b': 2 }, { 'd': 4 }]
13424      * };
13425      *
13426      * var other = {
13427      *   'a': [{ 'c': 3 }, { 'e': 5 }]
13428      * };
13429      *
13430      * _.merge(object, other);
13431      * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
13432      */
13433     var merge = createAssigner(function(object, source, srcIndex) {
13434       baseMerge(object, source, srcIndex);
13435     });
13436
13437     /**
13438      * This method is like `_.merge` except that it accepts `customizer` which
13439      * is invoked to produce the merged values of the destination and source
13440      * properties. If `customizer` returns `undefined`, merging is handled by the
13441      * method instead. The `customizer` is invoked with six arguments:
13442      * (objValue, srcValue, key, object, source, stack).
13443      *
13444      * **Note:** This method mutates `object`.
13445      *
13446      * @static
13447      * @memberOf _
13448      * @since 4.0.0
13449      * @category Object
13450      * @param {Object} object The destination object.
13451      * @param {...Object} sources The source objects.
13452      * @param {Function} customizer The function to customize assigned values.
13453      * @returns {Object} Returns `object`.
13454      * @example
13455      *
13456      * function customizer(objValue, srcValue) {
13457      *   if (_.isArray(objValue)) {
13458      *     return objValue.concat(srcValue);
13459      *   }
13460      * }
13461      *
13462      * var object = { 'a': [1], 'b': [2] };
13463      * var other = { 'a': [3], 'b': [4] };
13464      *
13465      * _.mergeWith(object, other, customizer);
13466      * // => { 'a': [1, 3], 'b': [2, 4] }
13467      */
13468     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
13469       baseMerge(object, source, srcIndex, customizer);
13470     });
13471
13472     /**
13473      * The opposite of `_.pick`; this method creates an object composed of the
13474      * own and inherited enumerable property paths of `object` that are not omitted.
13475      *
13476      * **Note:** This method is considerably slower than `_.pick`.
13477      *
13478      * @static
13479      * @since 0.1.0
13480      * @memberOf _
13481      * @category Object
13482      * @param {Object} object The source object.
13483      * @param {...(string|string[])} [paths] The property paths to omit.
13484      * @returns {Object} Returns the new object.
13485      * @example
13486      *
13487      * var object = { 'a': 1, 'b': '2', 'c': 3 };
13488      *
13489      * _.omit(object, ['a', 'c']);
13490      * // => { 'b': '2' }
13491      */
13492     var omit = flatRest(function(object, paths) {
13493       var result = {};
13494       if (object == null) {
13495         return result;
13496       }
13497       var isDeep = false;
13498       paths = arrayMap(paths, function(path) {
13499         path = castPath(path, object);
13500         isDeep || (isDeep = path.length > 1);
13501         return path;
13502       });
13503       copyObject(object, getAllKeysIn(object), result);
13504       if (isDeep) {
13505         result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
13506       }
13507       var length = paths.length;
13508       while (length--) {
13509         baseUnset(result, paths[length]);
13510       }
13511       return result;
13512     });
13513
13514     /**
13515      * The opposite of `_.pickBy`; this method creates an object composed of
13516      * the own and inherited enumerable string keyed properties of `object` that
13517      * `predicate` doesn't return truthy for. The predicate is invoked with two
13518      * arguments: (value, key).
13519      *
13520      * @static
13521      * @memberOf _
13522      * @since 4.0.0
13523      * @category Object
13524      * @param {Object} object The source object.
13525      * @param {Function} [predicate=_.identity] The function invoked per property.
13526      * @returns {Object} Returns the new object.
13527      * @example
13528      *
13529      * var object = { 'a': 1, 'b': '2', 'c': 3 };
13530      *
13531      * _.omitBy(object, _.isNumber);
13532      * // => { 'b': '2' }
13533      */
13534     function omitBy(object, predicate) {
13535       return pickBy(object, negate(getIteratee(predicate)));
13536     }
13537
13538     /**
13539      * Creates an object composed of the picked `object` properties.
13540      *
13541      * @static
13542      * @since 0.1.0
13543      * @memberOf _
13544      * @category Object
13545      * @param {Object} object The source object.
13546      * @param {...(string|string[])} [paths] The property paths to pick.
13547      * @returns {Object} Returns the new object.
13548      * @example
13549      *
13550      * var object = { 'a': 1, 'b': '2', 'c': 3 };
13551      *
13552      * _.pick(object, ['a', 'c']);
13553      * // => { 'a': 1, 'c': 3 }
13554      */
13555     var pick = flatRest(function(object, paths) {
13556       return object == null ? {} : basePick(object, paths);
13557     });
13558
13559     /**
13560      * Creates an object composed of the `object` properties `predicate` returns
13561      * truthy for. The predicate is invoked with two arguments: (value, key).
13562      *
13563      * @static
13564      * @memberOf _
13565      * @since 4.0.0
13566      * @category Object
13567      * @param {Object} object The source object.
13568      * @param {Function} [predicate=_.identity] The function invoked per property.
13569      * @returns {Object} Returns the new object.
13570      * @example
13571      *
13572      * var object = { 'a': 1, 'b': '2', 'c': 3 };
13573      *
13574      * _.pickBy(object, _.isNumber);
13575      * // => { 'a': 1, 'c': 3 }
13576      */
13577     function pickBy(object, predicate) {
13578       if (object == null) {
13579         return {};
13580       }
13581       var props = arrayMap(getAllKeysIn(object), function(prop) {
13582         return [prop];
13583       });
13584       predicate = getIteratee(predicate);
13585       return basePickBy(object, props, function(value, path) {
13586         return predicate(value, path[0]);
13587       });
13588     }
13589
13590     /**
13591      * This method is like `_.get` except that if the resolved value is a
13592      * function it's invoked with the `this` binding of its parent object and
13593      * its result is returned.
13594      *
13595      * @static
13596      * @since 0.1.0
13597      * @memberOf _
13598      * @category Object
13599      * @param {Object} object The object to query.
13600      * @param {Array|string} path The path of the property to resolve.
13601      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13602      * @returns {*} Returns the resolved value.
13603      * @example
13604      *
13605      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
13606      *
13607      * _.result(object, 'a[0].b.c1');
13608      * // => 3
13609      *
13610      * _.result(object, 'a[0].b.c2');
13611      * // => 4
13612      *
13613      * _.result(object, 'a[0].b.c3', 'default');
13614      * // => 'default'
13615      *
13616      * _.result(object, 'a[0].b.c3', _.constant('default'));
13617      * // => 'default'
13618      */
13619     function result(object, path, defaultValue) {
13620       path = castPath(path, object);
13621
13622       var index = -1,
13623           length = path.length;
13624
13625       // Ensure the loop is entered when path is empty.
13626       if (!length) {
13627         length = 1;
13628         object = undefined;
13629       }
13630       while (++index < length) {
13631         var value = object == null ? undefined : object[toKey(path[index])];
13632         if (value === undefined) {
13633           index = length;
13634           value = defaultValue;
13635         }
13636         object = isFunction(value) ? value.call(object) : value;
13637       }
13638       return object;
13639     }
13640
13641     /**
13642      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
13643      * it's created. Arrays are created for missing index properties while objects
13644      * are created for all other missing properties. Use `_.setWith` to customize
13645      * `path` creation.
13646      *
13647      * **Note:** This method mutates `object`.
13648      *
13649      * @static
13650      * @memberOf _
13651      * @since 3.7.0
13652      * @category Object
13653      * @param {Object} object The object to modify.
13654      * @param {Array|string} path The path of the property to set.
13655      * @param {*} value The value to set.
13656      * @returns {Object} Returns `object`.
13657      * @example
13658      *
13659      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13660      *
13661      * _.set(object, 'a[0].b.c', 4);
13662      * console.log(object.a[0].b.c);
13663      * // => 4
13664      *
13665      * _.set(object, ['x', '0', 'y', 'z'], 5);
13666      * console.log(object.x[0].y.z);
13667      * // => 5
13668      */
13669     function set(object, path, value) {
13670       return object == null ? object : baseSet(object, path, value);
13671     }
13672
13673     /**
13674      * This method is like `_.set` except that it accepts `customizer` which is
13675      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13676      * path creation is handled by the method instead. The `customizer` is invoked
13677      * with three arguments: (nsValue, key, nsObject).
13678      *
13679      * **Note:** This method mutates `object`.
13680      *
13681      * @static
13682      * @memberOf _
13683      * @since 4.0.0
13684      * @category Object
13685      * @param {Object} object The object to modify.
13686      * @param {Array|string} path The path of the property to set.
13687      * @param {*} value The value to set.
13688      * @param {Function} [customizer] The function to customize assigned values.
13689      * @returns {Object} Returns `object`.
13690      * @example
13691      *
13692      * var object = {};
13693      *
13694      * _.setWith(object, '[0][1]', 'a', Object);
13695      * // => { '0': { '1': 'a' } }
13696      */
13697     function setWith(object, path, value, customizer) {
13698       customizer = typeof customizer == 'function' ? customizer : undefined;
13699       return object == null ? object : baseSet(object, path, value, customizer);
13700     }
13701
13702     /**
13703      * Creates an array of own enumerable string keyed-value pairs for `object`
13704      * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13705      * entries are returned.
13706      *
13707      * @static
13708      * @memberOf _
13709      * @since 4.0.0
13710      * @alias entries
13711      * @category Object
13712      * @param {Object} object The object to query.
13713      * @returns {Array} Returns the key-value pairs.
13714      * @example
13715      *
13716      * function Foo() {
13717      *   this.a = 1;
13718      *   this.b = 2;
13719      * }
13720      *
13721      * Foo.prototype.c = 3;
13722      *
13723      * _.toPairs(new Foo);
13724      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13725      */
13726     var toPairs = createToPairs(keys);
13727
13728     /**
13729      * Creates an array of own and inherited enumerable string keyed-value pairs
13730      * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13731      * or set, its entries are returned.
13732      *
13733      * @static
13734      * @memberOf _
13735      * @since 4.0.0
13736      * @alias entriesIn
13737      * @category Object
13738      * @param {Object} object The object to query.
13739      * @returns {Array} Returns the key-value pairs.
13740      * @example
13741      *
13742      * function Foo() {
13743      *   this.a = 1;
13744      *   this.b = 2;
13745      * }
13746      *
13747      * Foo.prototype.c = 3;
13748      *
13749      * _.toPairsIn(new Foo);
13750      * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13751      */
13752     var toPairsIn = createToPairs(keysIn);
13753
13754     /**
13755      * An alternative to `_.reduce`; this method transforms `object` to a new
13756      * `accumulator` object which is the result of running each of its own
13757      * enumerable string keyed properties thru `iteratee`, with each invocation
13758      * potentially mutating the `accumulator` object. If `accumulator` is not
13759      * provided, a new object with the same `[[Prototype]]` will be used. The
13760      * iteratee is invoked with four arguments: (accumulator, value, key, object).
13761      * Iteratee functions may exit iteration early by explicitly returning `false`.
13762      *
13763      * @static
13764      * @memberOf _
13765      * @since 1.3.0
13766      * @category Object
13767      * @param {Object} object The object to iterate over.
13768      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13769      * @param {*} [accumulator] The custom accumulator value.
13770      * @returns {*} Returns the accumulated value.
13771      * @example
13772      *
13773      * _.transform([2, 3, 4], function(result, n) {
13774      *   result.push(n *= n);
13775      *   return n % 2 == 0;
13776      * }, []);
13777      * // => [4, 9]
13778      *
13779      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13780      *   (result[value] || (result[value] = [])).push(key);
13781      * }, {});
13782      * // => { '1': ['a', 'c'], '2': ['b'] }
13783      */
13784     function transform(object, iteratee, accumulator) {
13785       var isArr = isArray(object),
13786           isArrLike = isArr || isBuffer(object) || isTypedArray(object);
13787
13788       iteratee = getIteratee(iteratee, 4);
13789       if (accumulator == null) {
13790         var Ctor = object && object.constructor;
13791         if (isArrLike) {
13792           accumulator = isArr ? new Ctor : [];
13793         }
13794         else if (isObject(object)) {
13795           accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13796         }
13797         else {
13798           accumulator = {};
13799         }
13800       }
13801       (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
13802         return iteratee(accumulator, value, index, object);
13803       });
13804       return accumulator;
13805     }
13806
13807     /**
13808      * Removes the property at `path` of `object`.
13809      *
13810      * **Note:** This method mutates `object`.
13811      *
13812      * @static
13813      * @memberOf _
13814      * @since 4.0.0
13815      * @category Object
13816      * @param {Object} object The object to modify.
13817      * @param {Array|string} path The path of the property to unset.
13818      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13819      * @example
13820      *
13821      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13822      * _.unset(object, 'a[0].b.c');
13823      * // => true
13824      *
13825      * console.log(object);
13826      * // => { 'a': [{ 'b': {} }] };
13827      *
13828      * _.unset(object, ['a', '0', 'b', 'c']);
13829      * // => true
13830      *
13831      * console.log(object);
13832      * // => { 'a': [{ 'b': {} }] };
13833      */
13834     function unset(object, path) {
13835       return object == null ? true : baseUnset(object, path);
13836     }
13837
13838     /**
13839      * This method is like `_.set` except that accepts `updater` to produce the
13840      * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13841      * is invoked with one argument: (value).
13842      *
13843      * **Note:** This method mutates `object`.
13844      *
13845      * @static
13846      * @memberOf _
13847      * @since 4.6.0
13848      * @category Object
13849      * @param {Object} object The object to modify.
13850      * @param {Array|string} path The path of the property to set.
13851      * @param {Function} updater The function to produce the updated value.
13852      * @returns {Object} Returns `object`.
13853      * @example
13854      *
13855      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13856      *
13857      * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13858      * console.log(object.a[0].b.c);
13859      * // => 9
13860      *
13861      * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13862      * console.log(object.x[0].y.z);
13863      * // => 0
13864      */
13865     function update(object, path, updater) {
13866       return object == null ? object : baseUpdate(object, path, castFunction(updater));
13867     }
13868
13869     /**
13870      * This method is like `_.update` except that it accepts `customizer` which is
13871      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13872      * path creation is handled by the method instead. The `customizer` is invoked
13873      * with three arguments: (nsValue, key, nsObject).
13874      *
13875      * **Note:** This method mutates `object`.
13876      *
13877      * @static
13878      * @memberOf _
13879      * @since 4.6.0
13880      * @category Object
13881      * @param {Object} object The object to modify.
13882      * @param {Array|string} path The path of the property to set.
13883      * @param {Function} updater The function to produce the updated value.
13884      * @param {Function} [customizer] The function to customize assigned values.
13885      * @returns {Object} Returns `object`.
13886      * @example
13887      *
13888      * var object = {};
13889      *
13890      * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13891      * // => { '0': { '1': 'a' } }
13892      */
13893     function updateWith(object, path, updater, customizer) {
13894       customizer = typeof customizer == 'function' ? customizer : undefined;
13895       return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13896     }
13897
13898     /**
13899      * Creates an array of the own enumerable string keyed property values of `object`.
13900      *
13901      * **Note:** Non-object values are coerced to objects.
13902      *
13903      * @static
13904      * @since 0.1.0
13905      * @memberOf _
13906      * @category Object
13907      * @param {Object} object The object to query.
13908      * @returns {Array} Returns the array of property values.
13909      * @example
13910      *
13911      * function Foo() {
13912      *   this.a = 1;
13913      *   this.b = 2;
13914      * }
13915      *
13916      * Foo.prototype.c = 3;
13917      *
13918      * _.values(new Foo);
13919      * // => [1, 2] (iteration order is not guaranteed)
13920      *
13921      * _.values('hi');
13922      * // => ['h', 'i']
13923      */
13924     function values(object) {
13925       return object == null ? [] : baseValues(object, keys(object));
13926     }
13927
13928     /**
13929      * Creates an array of the own and inherited enumerable string keyed property
13930      * values of `object`.
13931      *
13932      * **Note:** Non-object values are coerced to objects.
13933      *
13934      * @static
13935      * @memberOf _
13936      * @since 3.0.0
13937      * @category Object
13938      * @param {Object} object The object to query.
13939      * @returns {Array} Returns the array of property values.
13940      * @example
13941      *
13942      * function Foo() {
13943      *   this.a = 1;
13944      *   this.b = 2;
13945      * }
13946      *
13947      * Foo.prototype.c = 3;
13948      *
13949      * _.valuesIn(new Foo);
13950      * // => [1, 2, 3] (iteration order is not guaranteed)
13951      */
13952     function valuesIn(object) {
13953       return object == null ? [] : baseValues(object, keysIn(object));
13954     }
13955
13956     /*------------------------------------------------------------------------*/
13957
13958     /**
13959      * Clamps `number` within the inclusive `lower` and `upper` bounds.
13960      *
13961      * @static
13962      * @memberOf _
13963      * @since 4.0.0
13964      * @category Number
13965      * @param {number} number The number to clamp.
13966      * @param {number} [lower] The lower bound.
13967      * @param {number} upper The upper bound.
13968      * @returns {number} Returns the clamped number.
13969      * @example
13970      *
13971      * _.clamp(-10, -5, 5);
13972      * // => -5
13973      *
13974      * _.clamp(10, -5, 5);
13975      * // => 5
13976      */
13977     function clamp(number, lower, upper) {
13978       if (upper === undefined) {
13979         upper = lower;
13980         lower = undefined;
13981       }
13982       if (upper !== undefined) {
13983         upper = toNumber(upper);
13984         upper = upper === upper ? upper : 0;
13985       }
13986       if (lower !== undefined) {
13987         lower = toNumber(lower);
13988         lower = lower === lower ? lower : 0;
13989       }
13990       return baseClamp(toNumber(number), lower, upper);
13991     }
13992
13993     /**
13994      * Checks if `n` is between `start` and up to, but not including, `end`. If
13995      * `end` is not specified, it's set to `start` with `start` then set to `0`.
13996      * If `start` is greater than `end` the params are swapped to support
13997      * negative ranges.
13998      *
13999      * @static
14000      * @memberOf _
14001      * @since 3.3.0
14002      * @category Number
14003      * @param {number} number The number to check.
14004      * @param {number} [start=0] The start of the range.
14005      * @param {number} end The end of the range.
14006      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
14007      * @see _.range, _.rangeRight
14008      * @example
14009      *
14010      * _.inRange(3, 2, 4);
14011      * // => true
14012      *
14013      * _.inRange(4, 8);
14014      * // => true
14015      *
14016      * _.inRange(4, 2);
14017      * // => false
14018      *
14019      * _.inRange(2, 2);
14020      * // => false
14021      *
14022      * _.inRange(1.2, 2);
14023      * // => true
14024      *
14025      * _.inRange(5.2, 4);
14026      * // => false
14027      *
14028      * _.inRange(-3, -2, -6);
14029      * // => true
14030      */
14031     function inRange(number, start, end) {
14032       start = toFinite(start);
14033       if (end === undefined) {
14034         end = start;
14035         start = 0;
14036       } else {
14037         end = toFinite(end);
14038       }
14039       number = toNumber(number);
14040       return baseInRange(number, start, end);
14041     }
14042
14043     /**
14044      * Produces a random number between the inclusive `lower` and `upper` bounds.
14045      * If only one argument is provided a number between `0` and the given number
14046      * is returned. If `floating` is `true`, or either `lower` or `upper` are
14047      * floats, a floating-point number is returned instead of an integer.
14048      *
14049      * **Note:** JavaScript follows the IEEE-754 standard for resolving
14050      * floating-point values which can produce unexpected results.
14051      *
14052      * @static
14053      * @memberOf _
14054      * @since 0.7.0
14055      * @category Number
14056      * @param {number} [lower=0] The lower bound.
14057      * @param {number} [upper=1] The upper bound.
14058      * @param {boolean} [floating] Specify returning a floating-point number.
14059      * @returns {number} Returns the random number.
14060      * @example
14061      *
14062      * _.random(0, 5);
14063      * // => an integer between 0 and 5
14064      *
14065      * _.random(5);
14066      * // => also an integer between 0 and 5
14067      *
14068      * _.random(5, true);
14069      * // => a floating-point number between 0 and 5
14070      *
14071      * _.random(1.2, 5.2);
14072      * // => a floating-point number between 1.2 and 5.2
14073      */
14074     function random(lower, upper, floating) {
14075       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
14076         upper = floating = undefined;
14077       }
14078       if (floating === undefined) {
14079         if (typeof upper == 'boolean') {
14080           floating = upper;
14081           upper = undefined;
14082         }
14083         else if (typeof lower == 'boolean') {
14084           floating = lower;
14085           lower = undefined;
14086         }
14087       }
14088       if (lower === undefined && upper === undefined) {
14089         lower = 0;
14090         upper = 1;
14091       }
14092       else {
14093         lower = toFinite(lower);
14094         if (upper === undefined) {
14095           upper = lower;
14096           lower = 0;
14097         } else {
14098           upper = toFinite(upper);
14099         }
14100       }
14101       if (lower > upper) {
14102         var temp = lower;
14103         lower = upper;
14104         upper = temp;
14105       }
14106       if (floating || lower % 1 || upper % 1) {
14107         var rand = nativeRandom();
14108         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
14109       }
14110       return baseRandom(lower, upper);
14111     }
14112
14113     /*------------------------------------------------------------------------*/
14114
14115     /**
14116      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
14117      *
14118      * @static
14119      * @memberOf _
14120      * @since 3.0.0
14121      * @category String
14122      * @param {string} [string=''] The string to convert.
14123      * @returns {string} Returns the camel cased string.
14124      * @example
14125      *
14126      * _.camelCase('Foo Bar');
14127      * // => 'fooBar'
14128      *
14129      * _.camelCase('--foo-bar--');
14130      * // => 'fooBar'
14131      *
14132      * _.camelCase('__FOO_BAR__');
14133      * // => 'fooBar'
14134      */
14135     var camelCase = createCompounder(function(result, word, index) {
14136       word = word.toLowerCase();
14137       return result + (index ? capitalize(word) : word);
14138     });
14139
14140     /**
14141      * Converts the first character of `string` to upper case and the remaining
14142      * to lower case.
14143      *
14144      * @static
14145      * @memberOf _
14146      * @since 3.0.0
14147      * @category String
14148      * @param {string} [string=''] The string to capitalize.
14149      * @returns {string} Returns the capitalized string.
14150      * @example
14151      *
14152      * _.capitalize('FRED');
14153      * // => 'Fred'
14154      */
14155     function capitalize(string) {
14156       return upperFirst(toString(string).toLowerCase());
14157     }
14158
14159     /**
14160      * Deburrs `string` by converting
14161      * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
14162      * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
14163      * letters to basic Latin letters and removing
14164      * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
14165      *
14166      * @static
14167      * @memberOf _
14168      * @since 3.0.0
14169      * @category String
14170      * @param {string} [string=''] The string to deburr.
14171      * @returns {string} Returns the deburred string.
14172      * @example
14173      *
14174      * _.deburr('déjà vu');
14175      * // => 'deja vu'
14176      */
14177     function deburr(string) {
14178       string = toString(string);
14179       return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
14180     }
14181
14182     /**
14183      * Checks if `string` ends with the given target string.
14184      *
14185      * @static
14186      * @memberOf _
14187      * @since 3.0.0
14188      * @category String
14189      * @param {string} [string=''] The string to inspect.
14190      * @param {string} [target] The string to search for.
14191      * @param {number} [position=string.length] The position to search up to.
14192      * @returns {boolean} Returns `true` if `string` ends with `target`,
14193      *  else `false`.
14194      * @example
14195      *
14196      * _.endsWith('abc', 'c');
14197      * // => true
14198      *
14199      * _.endsWith('abc', 'b');
14200      * // => false
14201      *
14202      * _.endsWith('abc', 'b', 2);
14203      * // => true
14204      */
14205     function endsWith(string, target, position) {
14206       string = toString(string);
14207       target = baseToString(target);
14208
14209       var length = string.length;
14210       position = position === undefined
14211         ? length
14212         : baseClamp(toInteger(position), 0, length);
14213
14214       var end = position;
14215       position -= target.length;
14216       return position >= 0 && string.slice(position, end) == target;
14217     }
14218
14219     /**
14220      * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
14221      * corresponding HTML entities.
14222      *
14223      * **Note:** No other characters are escaped. To escape additional
14224      * characters use a third-party library like [_he_](https://mths.be/he).
14225      *
14226      * Though the ">" character is escaped for symmetry, characters like
14227      * ">" and "/" don't need escaping in HTML and have no special meaning
14228      * unless they're part of a tag or unquoted attribute value. See
14229      * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
14230      * (under "semi-related fun fact") for more details.
14231      *
14232      * When working with HTML you should always
14233      * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
14234      * XSS vectors.
14235      *
14236      * @static
14237      * @since 0.1.0
14238      * @memberOf _
14239      * @category String
14240      * @param {string} [string=''] The string to escape.
14241      * @returns {string} Returns the escaped string.
14242      * @example
14243      *
14244      * _.escape('fred, barney, & pebbles');
14245      * // => 'fred, barney, &amp; pebbles'
14246      */
14247     function escape(string) {
14248       string = toString(string);
14249       return (string && reHasUnescapedHtml.test(string))
14250         ? string.replace(reUnescapedHtml, escapeHtmlChar)
14251         : string;
14252     }
14253
14254     /**
14255      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
14256      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
14257      *
14258      * @static
14259      * @memberOf _
14260      * @since 3.0.0
14261      * @category String
14262      * @param {string} [string=''] The string to escape.
14263      * @returns {string} Returns the escaped string.
14264      * @example
14265      *
14266      * _.escapeRegExp('[lodash](https://lodash.com/)');
14267      * // => '\[lodash\]\(https://lodash\.com/\)'
14268      */
14269     function escapeRegExp(string) {
14270       string = toString(string);
14271       return (string && reHasRegExpChar.test(string))
14272         ? string.replace(reRegExpChar, '\\$&')
14273         : string;
14274     }
14275
14276     /**
14277      * Converts `string` to
14278      * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
14279      *
14280      * @static
14281      * @memberOf _
14282      * @since 3.0.0
14283      * @category String
14284      * @param {string} [string=''] The string to convert.
14285      * @returns {string} Returns the kebab cased string.
14286      * @example
14287      *
14288      * _.kebabCase('Foo Bar');
14289      * // => 'foo-bar'
14290      *
14291      * _.kebabCase('fooBar');
14292      * // => 'foo-bar'
14293      *
14294      * _.kebabCase('__FOO_BAR__');
14295      * // => 'foo-bar'
14296      */
14297     var kebabCase = createCompounder(function(result, word, index) {
14298       return result + (index ? '-' : '') + word.toLowerCase();
14299     });
14300
14301     /**
14302      * Converts `string`, as space separated words, to lower case.
14303      *
14304      * @static
14305      * @memberOf _
14306      * @since 4.0.0
14307      * @category String
14308      * @param {string} [string=''] The string to convert.
14309      * @returns {string} Returns the lower cased string.
14310      * @example
14311      *
14312      * _.lowerCase('--Foo-Bar--');
14313      * // => 'foo bar'
14314      *
14315      * _.lowerCase('fooBar');
14316      * // => 'foo bar'
14317      *
14318      * _.lowerCase('__FOO_BAR__');
14319      * // => 'foo bar'
14320      */
14321     var lowerCase = createCompounder(function(result, word, index) {
14322       return result + (index ? ' ' : '') + word.toLowerCase();
14323     });
14324
14325     /**
14326      * Converts the first character of `string` to lower case.
14327      *
14328      * @static
14329      * @memberOf _
14330      * @since 4.0.0
14331      * @category String
14332      * @param {string} [string=''] The string to convert.
14333      * @returns {string} Returns the converted string.
14334      * @example
14335      *
14336      * _.lowerFirst('Fred');
14337      * // => 'fred'
14338      *
14339      * _.lowerFirst('FRED');
14340      * // => 'fRED'
14341      */
14342     var lowerFirst = createCaseFirst('toLowerCase');
14343
14344     /**
14345      * Pads `string` on the left and right sides if it's shorter than `length`.
14346      * Padding characters are truncated if they can't be evenly divided by `length`.
14347      *
14348      * @static
14349      * @memberOf _
14350      * @since 3.0.0
14351      * @category String
14352      * @param {string} [string=''] The string to pad.
14353      * @param {number} [length=0] The padding length.
14354      * @param {string} [chars=' '] The string used as padding.
14355      * @returns {string} Returns the padded string.
14356      * @example
14357      *
14358      * _.pad('abc', 8);
14359      * // => '  abc   '
14360      *
14361      * _.pad('abc', 8, '_-');
14362      * // => '_-abc_-_'
14363      *
14364      * _.pad('abc', 3);
14365      * // => 'abc'
14366      */
14367     function pad(string, length, chars) {
14368       string = toString(string);
14369       length = toInteger(length);
14370
14371       var strLength = length ? stringSize(string) : 0;
14372       if (!length || strLength >= length) {
14373         return string;
14374       }
14375       var mid = (length - strLength) / 2;
14376       return (
14377         createPadding(nativeFloor(mid), chars) +
14378         string +
14379         createPadding(nativeCeil(mid), chars)
14380       );
14381     }
14382
14383     /**
14384      * Pads `string` on the right side if it's shorter than `length`. Padding
14385      * characters are truncated if they exceed `length`.
14386      *
14387      * @static
14388      * @memberOf _
14389      * @since 4.0.0
14390      * @category String
14391      * @param {string} [string=''] The string to pad.
14392      * @param {number} [length=0] The padding length.
14393      * @param {string} [chars=' '] The string used as padding.
14394      * @returns {string} Returns the padded string.
14395      * @example
14396      *
14397      * _.padEnd('abc', 6);
14398      * // => 'abc   '
14399      *
14400      * _.padEnd('abc', 6, '_-');
14401      * // => 'abc_-_'
14402      *
14403      * _.padEnd('abc', 3);
14404      * // => 'abc'
14405      */
14406     function padEnd(string, length, chars) {
14407       string = toString(string);
14408       length = toInteger(length);
14409
14410       var strLength = length ? stringSize(string) : 0;
14411       return (length && strLength < length)
14412         ? (string + createPadding(length - strLength, chars))
14413         : string;
14414     }
14415
14416     /**
14417      * Pads `string` on the left side if it's shorter than `length`. Padding
14418      * characters are truncated if they exceed `length`.
14419      *
14420      * @static
14421      * @memberOf _
14422      * @since 4.0.0
14423      * @category String
14424      * @param {string} [string=''] The string to pad.
14425      * @param {number} [length=0] The padding length.
14426      * @param {string} [chars=' '] The string used as padding.
14427      * @returns {string} Returns the padded string.
14428      * @example
14429      *
14430      * _.padStart('abc', 6);
14431      * // => '   abc'
14432      *
14433      * _.padStart('abc', 6, '_-');
14434      * // => '_-_abc'
14435      *
14436      * _.padStart('abc', 3);
14437      * // => 'abc'
14438      */
14439     function padStart(string, length, chars) {
14440       string = toString(string);
14441       length = toInteger(length);
14442
14443       var strLength = length ? stringSize(string) : 0;
14444       return (length && strLength < length)
14445         ? (createPadding(length - strLength, chars) + string)
14446         : string;
14447     }
14448
14449     /**
14450      * Converts `string` to an integer of the specified radix. If `radix` is
14451      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
14452      * hexadecimal, in which case a `radix` of `16` is used.
14453      *
14454      * **Note:** This method aligns with the
14455      * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
14456      *
14457      * @static
14458      * @memberOf _
14459      * @since 1.1.0
14460      * @category String
14461      * @param {string} string The string to convert.
14462      * @param {number} [radix=10] The radix to interpret `value` by.
14463      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14464      * @returns {number} Returns the converted integer.
14465      * @example
14466      *
14467      * _.parseInt('08');
14468      * // => 8
14469      *
14470      * _.map(['6', '08', '10'], _.parseInt);
14471      * // => [6, 8, 10]
14472      */
14473     function parseInt(string, radix, guard) {
14474       if (guard || radix == null) {
14475         radix = 0;
14476       } else if (radix) {
14477         radix = +radix;
14478       }
14479       return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
14480     }
14481
14482     /**
14483      * Repeats the given string `n` times.
14484      *
14485      * @static
14486      * @memberOf _
14487      * @since 3.0.0
14488      * @category String
14489      * @param {string} [string=''] The string to repeat.
14490      * @param {number} [n=1] The number of times to repeat the string.
14491      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14492      * @returns {string} Returns the repeated string.
14493      * @example
14494      *
14495      * _.repeat('*', 3);
14496      * // => '***'
14497      *
14498      * _.repeat('abc', 2);
14499      * // => 'abcabc'
14500      *
14501      * _.repeat('abc', 0);
14502      * // => ''
14503      */
14504     function repeat(string, n, guard) {
14505       if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
14506         n = 1;
14507       } else {
14508         n = toInteger(n);
14509       }
14510       return baseRepeat(toString(string), n);
14511     }
14512
14513     /**
14514      * Replaces matches for `pattern` in `string` with `replacement`.
14515      *
14516      * **Note:** This method is based on
14517      * [`String#replace`](https://mdn.io/String/replace).
14518      *
14519      * @static
14520      * @memberOf _
14521      * @since 4.0.0
14522      * @category String
14523      * @param {string} [string=''] The string to modify.
14524      * @param {RegExp|string} pattern The pattern to replace.
14525      * @param {Function|string} replacement The match replacement.
14526      * @returns {string} Returns the modified string.
14527      * @example
14528      *
14529      * _.replace('Hi Fred', 'Fred', 'Barney');
14530      * // => 'Hi Barney'
14531      */
14532     function replace() {
14533       var args = arguments,
14534           string = toString(args[0]);
14535
14536       return args.length < 3 ? string : string.replace(args[1], args[2]);
14537     }
14538
14539     /**
14540      * Converts `string` to
14541      * [snake case](https://en.wikipedia.org/wiki/Snake_case).
14542      *
14543      * @static
14544      * @memberOf _
14545      * @since 3.0.0
14546      * @category String
14547      * @param {string} [string=''] The string to convert.
14548      * @returns {string} Returns the snake cased string.
14549      * @example
14550      *
14551      * _.snakeCase('Foo Bar');
14552      * // => 'foo_bar'
14553      *
14554      * _.snakeCase('fooBar');
14555      * // => 'foo_bar'
14556      *
14557      * _.snakeCase('--FOO-BAR--');
14558      * // => 'foo_bar'
14559      */
14560     var snakeCase = createCompounder(function(result, word, index) {
14561       return result + (index ? '_' : '') + word.toLowerCase();
14562     });
14563
14564     /**
14565      * Splits `string` by `separator`.
14566      *
14567      * **Note:** This method is based on
14568      * [`String#split`](https://mdn.io/String/split).
14569      *
14570      * @static
14571      * @memberOf _
14572      * @since 4.0.0
14573      * @category String
14574      * @param {string} [string=''] The string to split.
14575      * @param {RegExp|string} separator The separator pattern to split by.
14576      * @param {number} [limit] The length to truncate results to.
14577      * @returns {Array} Returns the string segments.
14578      * @example
14579      *
14580      * _.split('a-b-c', '-', 2);
14581      * // => ['a', 'b']
14582      */
14583     function split(string, separator, limit) {
14584       if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
14585         separator = limit = undefined;
14586       }
14587       limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
14588       if (!limit) {
14589         return [];
14590       }
14591       string = toString(string);
14592       if (string && (
14593             typeof separator == 'string' ||
14594             (separator != null && !isRegExp(separator))
14595           )) {
14596         separator = baseToString(separator);
14597         if (!separator && hasUnicode(string)) {
14598           return castSlice(stringToArray(string), 0, limit);
14599         }
14600       }
14601       return string.split(separator, limit);
14602     }
14603
14604     /**
14605      * Converts `string` to
14606      * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
14607      *
14608      * @static
14609      * @memberOf _
14610      * @since 3.1.0
14611      * @category String
14612      * @param {string} [string=''] The string to convert.
14613      * @returns {string} Returns the start cased string.
14614      * @example
14615      *
14616      * _.startCase('--foo-bar--');
14617      * // => 'Foo Bar'
14618      *
14619      * _.startCase('fooBar');
14620      * // => 'Foo Bar'
14621      *
14622      * _.startCase('__FOO_BAR__');
14623      * // => 'FOO BAR'
14624      */
14625     var startCase = createCompounder(function(result, word, index) {
14626       return result + (index ? ' ' : '') + upperFirst(word);
14627     });
14628
14629     /**
14630      * Checks if `string` starts with the given target string.
14631      *
14632      * @static
14633      * @memberOf _
14634      * @since 3.0.0
14635      * @category String
14636      * @param {string} [string=''] The string to inspect.
14637      * @param {string} [target] The string to search for.
14638      * @param {number} [position=0] The position to search from.
14639      * @returns {boolean} Returns `true` if `string` starts with `target`,
14640      *  else `false`.
14641      * @example
14642      *
14643      * _.startsWith('abc', 'a');
14644      * // => true
14645      *
14646      * _.startsWith('abc', 'b');
14647      * // => false
14648      *
14649      * _.startsWith('abc', 'b', 1);
14650      * // => true
14651      */
14652     function startsWith(string, target, position) {
14653       string = toString(string);
14654       position = position == null
14655         ? 0
14656         : baseClamp(toInteger(position), 0, string.length);
14657
14658       target = baseToString(target);
14659       return string.slice(position, position + target.length) == target;
14660     }
14661
14662     /**
14663      * Creates a compiled template function that can interpolate data properties
14664      * in "interpolate" delimiters, HTML-escape interpolated data properties in
14665      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
14666      * properties may be accessed as free variables in the template. If a setting
14667      * object is given, it takes precedence over `_.templateSettings` values.
14668      *
14669      * **Note:** In the development build `_.template` utilizes
14670      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14671      * for easier debugging.
14672      *
14673      * For more information on precompiling templates see
14674      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14675      *
14676      * For more information on Chrome extension sandboxes see
14677      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14678      *
14679      * @static
14680      * @since 0.1.0
14681      * @memberOf _
14682      * @category String
14683      * @param {string} [string=''] The template string.
14684      * @param {Object} [options={}] The options object.
14685      * @param {RegExp} [options.escape=_.templateSettings.escape]
14686      *  The HTML "escape" delimiter.
14687      * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14688      *  The "evaluate" delimiter.
14689      * @param {Object} [options.imports=_.templateSettings.imports]
14690      *  An object to import into the template as free variables.
14691      * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14692      *  The "interpolate" delimiter.
14693      * @param {string} [options.sourceURL='lodash.templateSources[n]']
14694      *  The sourceURL of the compiled template.
14695      * @param {string} [options.variable='obj']
14696      *  The data object variable name.
14697      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14698      * @returns {Function} Returns the compiled template function.
14699      * @example
14700      *
14701      * // Use the "interpolate" delimiter to create a compiled template.
14702      * var compiled = _.template('hello <%= user %>!');
14703      * compiled({ 'user': 'fred' });
14704      * // => 'hello fred!'
14705      *
14706      * // Use the HTML "escape" delimiter to escape data property values.
14707      * var compiled = _.template('<b><%- value %></b>');
14708      * compiled({ 'value': '<script>' });
14709      * // => '<b>&lt;script&gt;</b>'
14710      *
14711      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14712      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14713      * compiled({ 'users': ['fred', 'barney'] });
14714      * // => '<li>fred</li><li>barney</li>'
14715      *
14716      * // Use the internal `print` function in "evaluate" delimiters.
14717      * var compiled = _.template('<% print("hello " + user); %>!');
14718      * compiled({ 'user': 'barney' });
14719      * // => 'hello barney!'
14720      *
14721      * // Use the ES template literal delimiter as an "interpolate" delimiter.
14722      * // Disable support by replacing the "interpolate" delimiter.
14723      * var compiled = _.template('hello ${ user }!');
14724      * compiled({ 'user': 'pebbles' });
14725      * // => 'hello pebbles!'
14726      *
14727      * // Use backslashes to treat delimiters as plain text.
14728      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14729      * compiled({ 'value': 'ignored' });
14730      * // => '<%- value %>'
14731      *
14732      * // Use the `imports` option to import `jQuery` as `jq`.
14733      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14734      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14735      * compiled({ 'users': ['fred', 'barney'] });
14736      * // => '<li>fred</li><li>barney</li>'
14737      *
14738      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14739      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14740      * compiled(data);
14741      * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14742      *
14743      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14744      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14745      * compiled.source;
14746      * // => function(data) {
14747      * //   var __t, __p = '';
14748      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14749      * //   return __p;
14750      * // }
14751      *
14752      * // Use custom template delimiters.
14753      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14754      * var compiled = _.template('hello {{ user }}!');
14755      * compiled({ 'user': 'mustache' });
14756      * // => 'hello mustache!'
14757      *
14758      * // Use the `source` property to inline compiled templates for meaningful
14759      * // line numbers in error messages and stack traces.
14760      * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14761      *   var JST = {\
14762      *     "main": ' + _.template(mainText).source + '\
14763      *   };\
14764      * ');
14765      */
14766     function template(string, options, guard) {
14767       // Based on John Resig's `tmpl` implementation
14768       // (http://ejohn.org/blog/javascript-micro-templating/)
14769       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14770       var settings = lodash.templateSettings;
14771
14772       if (guard && isIterateeCall(string, options, guard)) {
14773         options = undefined;
14774       }
14775       string = toString(string);
14776       options = assignInWith({}, options, settings, customDefaultsAssignIn);
14777
14778       var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
14779           importsKeys = keys(imports),
14780           importsValues = baseValues(imports, importsKeys);
14781
14782       var isEscaping,
14783           isEvaluating,
14784           index = 0,
14785           interpolate = options.interpolate || reNoMatch,
14786           source = "__p += '";
14787
14788       // Compile the regexp to match each delimiter.
14789       var reDelimiters = RegExp(
14790         (options.escape || reNoMatch).source + '|' +
14791         interpolate.source + '|' +
14792         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14793         (options.evaluate || reNoMatch).source + '|$'
14794       , 'g');
14795
14796       // Use a sourceURL for easier debugging.
14797       var sourceURL = '//# sourceURL=' +
14798         ('sourceURL' in options
14799           ? options.sourceURL
14800           : ('lodash.templateSources[' + (++templateCounter) + ']')
14801         ) + '\n';
14802
14803       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14804         interpolateValue || (interpolateValue = esTemplateValue);
14805
14806         // Escape characters that can't be included in string literals.
14807         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14808
14809         // Replace delimiters with snippets.
14810         if (escapeValue) {
14811           isEscaping = true;
14812           source += "' +\n__e(" + escapeValue + ") +\n'";
14813         }
14814         if (evaluateValue) {
14815           isEvaluating = true;
14816           source += "';\n" + evaluateValue + ";\n__p += '";
14817         }
14818         if (interpolateValue) {
14819           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14820         }
14821         index = offset + match.length;
14822
14823         // The JS engine embedded in Adobe products needs `match` returned in
14824         // order to produce the correct `offset` value.
14825         return match;
14826       });
14827
14828       source += "';\n";
14829
14830       // If `variable` is not specified wrap a with-statement around the generated
14831       // code to add the data object to the top of the scope chain.
14832       var variable = options.variable;
14833       if (!variable) {
14834         source = 'with (obj) {\n' + source + '\n}\n';
14835       }
14836       // Cleanup code by stripping empty strings.
14837       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14838         .replace(reEmptyStringMiddle, '$1')
14839         .replace(reEmptyStringTrailing, '$1;');
14840
14841       // Frame code as the function body.
14842       source = 'function(' + (variable || 'obj') + ') {\n' +
14843         (variable
14844           ? ''
14845           : 'obj || (obj = {});\n'
14846         ) +
14847         "var __t, __p = ''" +
14848         (isEscaping
14849            ? ', __e = _.escape'
14850            : ''
14851         ) +
14852         (isEvaluating
14853           ? ', __j = Array.prototype.join;\n' +
14854             "function print() { __p += __j.call(arguments, '') }\n"
14855           : ';\n'
14856         ) +
14857         source +
14858         'return __p\n}';
14859
14860       var result = attempt(function() {
14861         return Function(importsKeys, sourceURL + 'return ' + source)
14862           .apply(undefined, importsValues);
14863       });
14864
14865       // Provide the compiled function's source by its `toString` method or
14866       // the `source` property as a convenience for inlining compiled templates.
14867       result.source = source;
14868       if (isError(result)) {
14869         throw result;
14870       }
14871       return result;
14872     }
14873
14874     /**
14875      * Converts `string`, as a whole, to lower case just like
14876      * [String#toLowerCase](https://mdn.io/toLowerCase).
14877      *
14878      * @static
14879      * @memberOf _
14880      * @since 4.0.0
14881      * @category String
14882      * @param {string} [string=''] The string to convert.
14883      * @returns {string} Returns the lower cased string.
14884      * @example
14885      *
14886      * _.toLower('--Foo-Bar--');
14887      * // => '--foo-bar--'
14888      *
14889      * _.toLower('fooBar');
14890      * // => 'foobar'
14891      *
14892      * _.toLower('__FOO_BAR__');
14893      * // => '__foo_bar__'
14894      */
14895     function toLower(value) {
14896       return toString(value).toLowerCase();
14897     }
14898
14899     /**
14900      * Converts `string`, as a whole, to upper case just like
14901      * [String#toUpperCase](https://mdn.io/toUpperCase).
14902      *
14903      * @static
14904      * @memberOf _
14905      * @since 4.0.0
14906      * @category String
14907      * @param {string} [string=''] The string to convert.
14908      * @returns {string} Returns the upper cased string.
14909      * @example
14910      *
14911      * _.toUpper('--foo-bar--');
14912      * // => '--FOO-BAR--'
14913      *
14914      * _.toUpper('fooBar');
14915      * // => 'FOOBAR'
14916      *
14917      * _.toUpper('__foo_bar__');
14918      * // => '__FOO_BAR__'
14919      */
14920     function toUpper(value) {
14921       return toString(value).toUpperCase();
14922     }
14923
14924     /**
14925      * Removes leading and trailing whitespace or specified characters from `string`.
14926      *
14927      * @static
14928      * @memberOf _
14929      * @since 3.0.0
14930      * @category String
14931      * @param {string} [string=''] The string to trim.
14932      * @param {string} [chars=whitespace] The characters to trim.
14933      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14934      * @returns {string} Returns the trimmed string.
14935      * @example
14936      *
14937      * _.trim('  abc  ');
14938      * // => 'abc'
14939      *
14940      * _.trim('-_-abc-_-', '_-');
14941      * // => 'abc'
14942      *
14943      * _.map(['  foo  ', '  bar  '], _.trim);
14944      * // => ['foo', 'bar']
14945      */
14946     function trim(string, chars, guard) {
14947       string = toString(string);
14948       if (string && (guard || chars === undefined)) {
14949         return string.replace(reTrim, '');
14950       }
14951       if (!string || !(chars = baseToString(chars))) {
14952         return string;
14953       }
14954       var strSymbols = stringToArray(string),
14955           chrSymbols = stringToArray(chars),
14956           start = charsStartIndex(strSymbols, chrSymbols),
14957           end = charsEndIndex(strSymbols, chrSymbols) + 1;
14958
14959       return castSlice(strSymbols, start, end).join('');
14960     }
14961
14962     /**
14963      * Removes trailing whitespace or specified characters from `string`.
14964      *
14965      * @static
14966      * @memberOf _
14967      * @since 4.0.0
14968      * @category String
14969      * @param {string} [string=''] The string to trim.
14970      * @param {string} [chars=whitespace] The characters to trim.
14971      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14972      * @returns {string} Returns the trimmed string.
14973      * @example
14974      *
14975      * _.trimEnd('  abc  ');
14976      * // => '  abc'
14977      *
14978      * _.trimEnd('-_-abc-_-', '_-');
14979      * // => '-_-abc'
14980      */
14981     function trimEnd(string, chars, guard) {
14982       string = toString(string);
14983       if (string && (guard || chars === undefined)) {
14984         return string.replace(reTrimEnd, '');
14985       }
14986       if (!string || !(chars = baseToString(chars))) {
14987         return string;
14988       }
14989       var strSymbols = stringToArray(string),
14990           end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14991
14992       return castSlice(strSymbols, 0, end).join('');
14993     }
14994
14995     /**
14996      * Removes leading whitespace or specified characters from `string`.
14997      *
14998      * @static
14999      * @memberOf _
15000      * @since 4.0.0
15001      * @category String
15002      * @param {string} [string=''] The string to trim.
15003      * @param {string} [chars=whitespace] The characters to trim.
15004      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15005      * @returns {string} Returns the trimmed string.
15006      * @example
15007      *
15008      * _.trimStart('  abc  ');
15009      * // => 'abc  '
15010      *
15011      * _.trimStart('-_-abc-_-', '_-');
15012      * // => 'abc-_-'
15013      */
15014     function trimStart(string, chars, guard) {
15015       string = toString(string);
15016       if (string && (guard || chars === undefined)) {
15017         return string.replace(reTrimStart, '');
15018       }
15019       if (!string || !(chars = baseToString(chars))) {
15020         return string;
15021       }
15022       var strSymbols = stringToArray(string),
15023           start = charsStartIndex(strSymbols, stringToArray(chars));
15024
15025       return castSlice(strSymbols, start).join('');
15026     }
15027
15028     /**
15029      * Truncates `string` if it's longer than the given maximum string length.
15030      * The last characters of the truncated string are replaced with the omission
15031      * string which defaults to "...".
15032      *
15033      * @static
15034      * @memberOf _
15035      * @since 4.0.0
15036      * @category String
15037      * @param {string} [string=''] The string to truncate.
15038      * @param {Object} [options={}] The options object.
15039      * @param {number} [options.length=30] The maximum string length.
15040      * @param {string} [options.omission='...'] The string to indicate text is omitted.
15041      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
15042      * @returns {string} Returns the truncated string.
15043      * @example
15044      *
15045      * _.truncate('hi-diddly-ho there, neighborino');
15046      * // => 'hi-diddly-ho there, neighbo...'
15047      *
15048      * _.truncate('hi-diddly-ho there, neighborino', {
15049      *   'length': 24,
15050      *   'separator': ' '
15051      * });
15052      * // => 'hi-diddly-ho there,...'
15053      *
15054      * _.truncate('hi-diddly-ho there, neighborino', {
15055      *   'length': 24,
15056      *   'separator': /,? +/
15057      * });
15058      * // => 'hi-diddly-ho there...'
15059      *
15060      * _.truncate('hi-diddly-ho there, neighborino', {
15061      *   'omission': ' [...]'
15062      * });
15063      * // => 'hi-diddly-ho there, neig [...]'
15064      */
15065     function truncate(string, options) {
15066       var length = DEFAULT_TRUNC_LENGTH,
15067           omission = DEFAULT_TRUNC_OMISSION;
15068
15069       if (isObject(options)) {
15070         var separator = 'separator' in options ? options.separator : separator;
15071         length = 'length' in options ? toInteger(options.length) : length;
15072         omission = 'omission' in options ? baseToString(options.omission) : omission;
15073       }
15074       string = toString(string);
15075
15076       var strLength = string.length;
15077       if (hasUnicode(string)) {
15078         var strSymbols = stringToArray(string);
15079         strLength = strSymbols.length;
15080       }
15081       if (length >= strLength) {
15082         return string;
15083       }
15084       var end = length - stringSize(omission);
15085       if (end < 1) {
15086         return omission;
15087       }
15088       var result = strSymbols
15089         ? castSlice(strSymbols, 0, end).join('')
15090         : string.slice(0, end);
15091
15092       if (separator === undefined) {
15093         return result + omission;
15094       }
15095       if (strSymbols) {
15096         end += (result.length - end);
15097       }
15098       if (isRegExp(separator)) {
15099         if (string.slice(end).search(separator)) {
15100           var match,
15101               substring = result;
15102
15103           if (!separator.global) {
15104             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
15105           }
15106           separator.lastIndex = 0;
15107           while ((match = separator.exec(substring))) {
15108             var newEnd = match.index;
15109           }
15110           result = result.slice(0, newEnd === undefined ? end : newEnd);
15111         }
15112       } else if (string.indexOf(baseToString(separator), end) != end) {
15113         var index = result.lastIndexOf(separator);
15114         if (index > -1) {
15115           result = result.slice(0, index);
15116         }
15117       }
15118       return result + omission;
15119     }
15120
15121     /**
15122      * The inverse of `_.escape`; this method converts the HTML entities
15123      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
15124      * their corresponding characters.
15125      *
15126      * **Note:** No other HTML entities are unescaped. To unescape additional
15127      * HTML entities use a third-party library like [_he_](https://mths.be/he).
15128      *
15129      * @static
15130      * @memberOf _
15131      * @since 0.6.0
15132      * @category String
15133      * @param {string} [string=''] The string to unescape.
15134      * @returns {string} Returns the unescaped string.
15135      * @example
15136      *
15137      * _.unescape('fred, barney, &amp; pebbles');
15138      * // => 'fred, barney, & pebbles'
15139      */
15140     function unescape(string) {
15141       string = toString(string);
15142       return (string && reHasEscapedHtml.test(string))
15143         ? string.replace(reEscapedHtml, unescapeHtmlChar)
15144         : string;
15145     }
15146
15147     /**
15148      * Converts `string`, as space separated words, to upper case.
15149      *
15150      * @static
15151      * @memberOf _
15152      * @since 4.0.0
15153      * @category String
15154      * @param {string} [string=''] The string to convert.
15155      * @returns {string} Returns the upper cased string.
15156      * @example
15157      *
15158      * _.upperCase('--foo-bar');
15159      * // => 'FOO BAR'
15160      *
15161      * _.upperCase('fooBar');
15162      * // => 'FOO BAR'
15163      *
15164      * _.upperCase('__foo_bar__');
15165      * // => 'FOO BAR'
15166      */
15167     var upperCase = createCompounder(function(result, word, index) {
15168       return result + (index ? ' ' : '') + word.toUpperCase();
15169     });
15170
15171     /**
15172      * Converts the first character of `string` to upper case.
15173      *
15174      * @static
15175      * @memberOf _
15176      * @since 4.0.0
15177      * @category String
15178      * @param {string} [string=''] The string to convert.
15179      * @returns {string} Returns the converted string.
15180      * @example
15181      *
15182      * _.upperFirst('fred');
15183      * // => 'Fred'
15184      *
15185      * _.upperFirst('FRED');
15186      * // => 'FRED'
15187      */
15188     var upperFirst = createCaseFirst('toUpperCase');
15189
15190     /**
15191      * Splits `string` into an array of its words.
15192      *
15193      * @static
15194      * @memberOf _
15195      * @since 3.0.0
15196      * @category String
15197      * @param {string} [string=''] The string to inspect.
15198      * @param {RegExp|string} [pattern] The pattern to match words.
15199      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15200      * @returns {Array} Returns the words of `string`.
15201      * @example
15202      *
15203      * _.words('fred, barney, & pebbles');
15204      * // => ['fred', 'barney', 'pebbles']
15205      *
15206      * _.words('fred, barney, & pebbles', /[^, ]+/g);
15207      * // => ['fred', 'barney', '&', 'pebbles']
15208      */
15209     function words(string, pattern, guard) {
15210       string = toString(string);
15211       pattern = guard ? undefined : pattern;
15212
15213       if (pattern === undefined) {
15214         return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
15215       }
15216       return string.match(pattern) || [];
15217     }
15218
15219     /*------------------------------------------------------------------------*/
15220
15221     /**
15222      * Attempts to invoke `func`, returning either the result or the caught error
15223      * object. Any additional arguments are provided to `func` when it's invoked.
15224      *
15225      * @static
15226      * @memberOf _
15227      * @since 3.0.0
15228      * @category Util
15229      * @param {Function} func The function to attempt.
15230      * @param {...*} [args] The arguments to invoke `func` with.
15231      * @returns {*} Returns the `func` result or error object.
15232      * @example
15233      *
15234      * // Avoid throwing errors for invalid selectors.
15235      * var elements = _.attempt(function(selector) {
15236      *   return document.querySelectorAll(selector);
15237      * }, '>_>');
15238      *
15239      * if (_.isError(elements)) {
15240      *   elements = [];
15241      * }
15242      */
15243     var attempt = baseRest(function(func, args) {
15244       try {
15245         return apply(func, undefined, args);
15246       } catch (e) {
15247         return isError(e) ? e : new Error(e);
15248       }
15249     });
15250
15251     /**
15252      * Binds methods of an object to the object itself, overwriting the existing
15253      * method.
15254      *
15255      * **Note:** This method doesn't set the "length" property of bound functions.
15256      *
15257      * @static
15258      * @since 0.1.0
15259      * @memberOf _
15260      * @category Util
15261      * @param {Object} object The object to bind and assign the bound methods to.
15262      * @param {...(string|string[])} methodNames The object method names to bind.
15263      * @returns {Object} Returns `object`.
15264      * @example
15265      *
15266      * var view = {
15267      *   'label': 'docs',
15268      *   'click': function() {
15269      *     console.log('clicked ' + this.label);
15270      *   }
15271      * };
15272      *
15273      * _.bindAll(view, ['click']);
15274      * jQuery(element).on('click', view.click);
15275      * // => Logs 'clicked docs' when clicked.
15276      */
15277     var bindAll = flatRest(function(object, methodNames) {
15278       arrayEach(methodNames, function(key) {
15279         key = toKey(key);
15280         baseAssignValue(object, key, bind(object[key], object));
15281       });
15282       return object;
15283     });
15284
15285     /**
15286      * Creates a function that iterates over `pairs` and invokes the corresponding
15287      * function of the first predicate to return truthy. The predicate-function
15288      * pairs are invoked with the `this` binding and arguments of the created
15289      * function.
15290      *
15291      * @static
15292      * @memberOf _
15293      * @since 4.0.0
15294      * @category Util
15295      * @param {Array} pairs The predicate-function pairs.
15296      * @returns {Function} Returns the new composite function.
15297      * @example
15298      *
15299      * var func = _.cond([
15300      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
15301      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
15302      *   [_.stubTrue,                      _.constant('no match')]
15303      * ]);
15304      *
15305      * func({ 'a': 1, 'b': 2 });
15306      * // => 'matches A'
15307      *
15308      * func({ 'a': 0, 'b': 1 });
15309      * // => 'matches B'
15310      *
15311      * func({ 'a': '1', 'b': '2' });
15312      * // => 'no match'
15313      */
15314     function cond(pairs) {
15315       var length = pairs == null ? 0 : pairs.length,
15316           toIteratee = getIteratee();
15317
15318       pairs = !length ? [] : arrayMap(pairs, function(pair) {
15319         if (typeof pair[1] != 'function') {
15320           throw new TypeError(FUNC_ERROR_TEXT);
15321         }
15322         return [toIteratee(pair[0]), pair[1]];
15323       });
15324
15325       return baseRest(function(args) {
15326         var index = -1;
15327         while (++index < length) {
15328           var pair = pairs[index];
15329           if (apply(pair[0], this, args)) {
15330             return apply(pair[1], this, args);
15331           }
15332         }
15333       });
15334     }
15335
15336     /**
15337      * Creates a function that invokes the predicate properties of `source` with
15338      * the corresponding property values of a given object, returning `true` if
15339      * all predicates return truthy, else `false`.
15340      *
15341      * **Note:** The created function is equivalent to `_.conformsTo` with
15342      * `source` partially applied.
15343      *
15344      * @static
15345      * @memberOf _
15346      * @since 4.0.0
15347      * @category Util
15348      * @param {Object} source The object of property predicates to conform to.
15349      * @returns {Function} Returns the new spec function.
15350      * @example
15351      *
15352      * var objects = [
15353      *   { 'a': 2, 'b': 1 },
15354      *   { 'a': 1, 'b': 2 }
15355      * ];
15356      *
15357      * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
15358      * // => [{ 'a': 1, 'b': 2 }]
15359      */
15360     function conforms(source) {
15361       return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
15362     }
15363
15364     /**
15365      * Creates a function that returns `value`.
15366      *
15367      * @static
15368      * @memberOf _
15369      * @since 2.4.0
15370      * @category Util
15371      * @param {*} value The value to return from the new function.
15372      * @returns {Function} Returns the new constant function.
15373      * @example
15374      *
15375      * var objects = _.times(2, _.constant({ 'a': 1 }));
15376      *
15377      * console.log(objects);
15378      * // => [{ 'a': 1 }, { 'a': 1 }]
15379      *
15380      * console.log(objects[0] === objects[1]);
15381      * // => true
15382      */
15383     function constant(value) {
15384       return function() {
15385         return value;
15386       };
15387     }
15388
15389     /**
15390      * Checks `value` to determine whether a default value should be returned in
15391      * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
15392      * or `undefined`.
15393      *
15394      * @static
15395      * @memberOf _
15396      * @since 4.14.0
15397      * @category Util
15398      * @param {*} value The value to check.
15399      * @param {*} defaultValue The default value.
15400      * @returns {*} Returns the resolved value.
15401      * @example
15402      *
15403      * _.defaultTo(1, 10);
15404      * // => 1
15405      *
15406      * _.defaultTo(undefined, 10);
15407      * // => 10
15408      */
15409     function defaultTo(value, defaultValue) {
15410       return (value == null || value !== value) ? defaultValue : value;
15411     }
15412
15413     /**
15414      * Creates a function that returns the result of invoking the given functions
15415      * with the `this` binding of the created function, where each successive
15416      * invocation is supplied the return value of the previous.
15417      *
15418      * @static
15419      * @memberOf _
15420      * @since 3.0.0
15421      * @category Util
15422      * @param {...(Function|Function[])} [funcs] The functions to invoke.
15423      * @returns {Function} Returns the new composite function.
15424      * @see _.flowRight
15425      * @example
15426      *
15427      * function square(n) {
15428      *   return n * n;
15429      * }
15430      *
15431      * var addSquare = _.flow([_.add, square]);
15432      * addSquare(1, 2);
15433      * // => 9
15434      */
15435     var flow = createFlow();
15436
15437     /**
15438      * This method is like `_.flow` except that it creates a function that
15439      * invokes the given functions from right to left.
15440      *
15441      * @static
15442      * @since 3.0.0
15443      * @memberOf _
15444      * @category Util
15445      * @param {...(Function|Function[])} [funcs] The functions to invoke.
15446      * @returns {Function} Returns the new composite function.
15447      * @see _.flow
15448      * @example
15449      *
15450      * function square(n) {
15451      *   return n * n;
15452      * }
15453      *
15454      * var addSquare = _.flowRight([square, _.add]);
15455      * addSquare(1, 2);
15456      * // => 9
15457      */
15458     var flowRight = createFlow(true);
15459
15460     /**
15461      * This method returns the first argument it receives.
15462      *
15463      * @static
15464      * @since 0.1.0
15465      * @memberOf _
15466      * @category Util
15467      * @param {*} value Any value.
15468      * @returns {*} Returns `value`.
15469      * @example
15470      *
15471      * var object = { 'a': 1 };
15472      *
15473      * console.log(_.identity(object) === object);
15474      * // => true
15475      */
15476     function identity(value) {
15477       return value;
15478     }
15479
15480     /**
15481      * Creates a function that invokes `func` with the arguments of the created
15482      * function. If `func` is a property name, the created function returns the
15483      * property value for a given element. If `func` is an array or object, the
15484      * created function returns `true` for elements that contain the equivalent
15485      * source properties, otherwise it returns `false`.
15486      *
15487      * @static
15488      * @since 4.0.0
15489      * @memberOf _
15490      * @category Util
15491      * @param {*} [func=_.identity] The value to convert to a callback.
15492      * @returns {Function} Returns the callback.
15493      * @example
15494      *
15495      * var users = [
15496      *   { 'user': 'barney', 'age': 36, 'active': true },
15497      *   { 'user': 'fred',   'age': 40, 'active': false }
15498      * ];
15499      *
15500      * // The `_.matches` iteratee shorthand.
15501      * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
15502      * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
15503      *
15504      * // The `_.matchesProperty` iteratee shorthand.
15505      * _.filter(users, _.iteratee(['user', 'fred']));
15506      * // => [{ 'user': 'fred', 'age': 40 }]
15507      *
15508      * // The `_.property` iteratee shorthand.
15509      * _.map(users, _.iteratee('user'));
15510      * // => ['barney', 'fred']
15511      *
15512      * // Create custom iteratee shorthands.
15513      * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
15514      *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
15515      *     return func.test(string);
15516      *   };
15517      * });
15518      *
15519      * _.filter(['abc', 'def'], /ef/);
15520      * // => ['def']
15521      */
15522     function iteratee(func) {
15523       return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
15524     }
15525
15526     /**
15527      * Creates a function that performs a partial deep comparison between a given
15528      * object and `source`, returning `true` if the given object has equivalent
15529      * property values, else `false`.
15530      *
15531      * **Note:** The created function is equivalent to `_.isMatch` with `source`
15532      * partially applied.
15533      *
15534      * Partial comparisons will match empty array and empty object `source`
15535      * values against any array or object value, respectively. See `_.isEqual`
15536      * for a list of supported value comparisons.
15537      *
15538      * @static
15539      * @memberOf _
15540      * @since 3.0.0
15541      * @category Util
15542      * @param {Object} source The object of property values to match.
15543      * @returns {Function} Returns the new spec function.
15544      * @example
15545      *
15546      * var objects = [
15547      *   { 'a': 1, 'b': 2, 'c': 3 },
15548      *   { 'a': 4, 'b': 5, 'c': 6 }
15549      * ];
15550      *
15551      * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
15552      * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
15553      */
15554     function matches(source) {
15555       return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
15556     }
15557
15558     /**
15559      * Creates a function that performs a partial deep comparison between the
15560      * value at `path` of a given object to `srcValue`, returning `true` if the
15561      * object value is equivalent, else `false`.
15562      *
15563      * **Note:** Partial comparisons will match empty array and empty object
15564      * `srcValue` values against any array or object value, respectively. See
15565      * `_.isEqual` for a list of supported value comparisons.
15566      *
15567      * @static
15568      * @memberOf _
15569      * @since 3.2.0
15570      * @category Util
15571      * @param {Array|string} path The path of the property to get.
15572      * @param {*} srcValue The value to match.
15573      * @returns {Function} Returns the new spec function.
15574      * @example
15575      *
15576      * var objects = [
15577      *   { 'a': 1, 'b': 2, 'c': 3 },
15578      *   { 'a': 4, 'b': 5, 'c': 6 }
15579      * ];
15580      *
15581      * _.find(objects, _.matchesProperty('a', 4));
15582      * // => { 'a': 4, 'b': 5, 'c': 6 }
15583      */
15584     function matchesProperty(path, srcValue) {
15585       return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
15586     }
15587
15588     /**
15589      * Creates a function that invokes the method at `path` of a given object.
15590      * Any additional arguments are provided to the invoked method.
15591      *
15592      * @static
15593      * @memberOf _
15594      * @since 3.7.0
15595      * @category Util
15596      * @param {Array|string} path The path of the method to invoke.
15597      * @param {...*} [args] The arguments to invoke the method with.
15598      * @returns {Function} Returns the new invoker function.
15599      * @example
15600      *
15601      * var objects = [
15602      *   { 'a': { 'b': _.constant(2) } },
15603      *   { 'a': { 'b': _.constant(1) } }
15604      * ];
15605      *
15606      * _.map(objects, _.method('a.b'));
15607      * // => [2, 1]
15608      *
15609      * _.map(objects, _.method(['a', 'b']));
15610      * // => [2, 1]
15611      */
15612     var method = baseRest(function(path, args) {
15613       return function(object) {
15614         return baseInvoke(object, path, args);
15615       };
15616     });
15617
15618     /**
15619      * The opposite of `_.method`; this method creates a function that invokes
15620      * the method at a given path of `object`. Any additional arguments are
15621      * provided to the invoked method.
15622      *
15623      * @static
15624      * @memberOf _
15625      * @since 3.7.0
15626      * @category Util
15627      * @param {Object} object The object to query.
15628      * @param {...*} [args] The arguments to invoke the method with.
15629      * @returns {Function} Returns the new invoker function.
15630      * @example
15631      *
15632      * var array = _.times(3, _.constant),
15633      *     object = { 'a': array, 'b': array, 'c': array };
15634      *
15635      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
15636      * // => [2, 0]
15637      *
15638      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
15639      * // => [2, 0]
15640      */
15641     var methodOf = baseRest(function(object, args) {
15642       return function(path) {
15643         return baseInvoke(object, path, args);
15644       };
15645     });
15646
15647     /**
15648      * Adds all own enumerable string keyed function properties of a source
15649      * object to the destination object. If `object` is a function, then methods
15650      * are added to its prototype as well.
15651      *
15652      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
15653      * avoid conflicts caused by modifying the original.
15654      *
15655      * @static
15656      * @since 0.1.0
15657      * @memberOf _
15658      * @category Util
15659      * @param {Function|Object} [object=lodash] The destination object.
15660      * @param {Object} source The object of functions to add.
15661      * @param {Object} [options={}] The options object.
15662      * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
15663      * @returns {Function|Object} Returns `object`.
15664      * @example
15665      *
15666      * function vowels(string) {
15667      *   return _.filter(string, function(v) {
15668      *     return /[aeiou]/i.test(v);
15669      *   });
15670      * }
15671      *
15672      * _.mixin({ 'vowels': vowels });
15673      * _.vowels('fred');
15674      * // => ['e']
15675      *
15676      * _('fred').vowels().value();
15677      * // => ['e']
15678      *
15679      * _.mixin({ 'vowels': vowels }, { 'chain': false });
15680      * _('fred').vowels();
15681      * // => ['e']
15682      */
15683     function mixin(object, source, options) {
15684       var props = keys(source),
15685           methodNames = baseFunctions(source, props);
15686
15687       if (options == null &&
15688           !(isObject(source) && (methodNames.length || !props.length))) {
15689         options = source;
15690         source = object;
15691         object = this;
15692         methodNames = baseFunctions(source, keys(source));
15693       }
15694       var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
15695           isFunc = isFunction(object);
15696
15697       arrayEach(methodNames, function(methodName) {
15698         var func = source[methodName];
15699         object[methodName] = func;
15700         if (isFunc) {
15701           object.prototype[methodName] = function() {
15702             var chainAll = this.__chain__;
15703             if (chain || chainAll) {
15704               var result = object(this.__wrapped__),
15705                   actions = result.__actions__ = copyArray(this.__actions__);
15706
15707               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15708               result.__chain__ = chainAll;
15709               return result;
15710             }
15711             return func.apply(object, arrayPush([this.value()], arguments));
15712           };
15713         }
15714       });
15715
15716       return object;
15717     }
15718
15719     /**
15720      * Reverts the `_` variable to its previous value and returns a reference to
15721      * the `lodash` function.
15722      *
15723      * @static
15724      * @since 0.1.0
15725      * @memberOf _
15726      * @category Util
15727      * @returns {Function} Returns the `lodash` function.
15728      * @example
15729      *
15730      * var lodash = _.noConflict();
15731      */
15732     function noConflict() {
15733       if (root._ === this) {
15734         root._ = oldDash;
15735       }
15736       return this;
15737     }
15738
15739     /**
15740      * This method returns `undefined`.
15741      *
15742      * @static
15743      * @memberOf _
15744      * @since 2.3.0
15745      * @category Util
15746      * @example
15747      *
15748      * _.times(2, _.noop);
15749      * // => [undefined, undefined]
15750      */
15751     function noop() {
15752       // No operation performed.
15753     }
15754
15755     /**
15756      * Creates a function that gets the argument at index `n`. If `n` is negative,
15757      * the nth argument from the end is returned.
15758      *
15759      * @static
15760      * @memberOf _
15761      * @since 4.0.0
15762      * @category Util
15763      * @param {number} [n=0] The index of the argument to return.
15764      * @returns {Function} Returns the new pass-thru function.
15765      * @example
15766      *
15767      * var func = _.nthArg(1);
15768      * func('a', 'b', 'c', 'd');
15769      * // => 'b'
15770      *
15771      * var func = _.nthArg(-2);
15772      * func('a', 'b', 'c', 'd');
15773      * // => 'c'
15774      */
15775     function nthArg(n) {
15776       n = toInteger(n);
15777       return baseRest(function(args) {
15778         return baseNth(args, n);
15779       });
15780     }
15781
15782     /**
15783      * Creates a function that invokes `iteratees` with the arguments it receives
15784      * and returns their results.
15785      *
15786      * @static
15787      * @memberOf _
15788      * @since 4.0.0
15789      * @category Util
15790      * @param {...(Function|Function[])} [iteratees=[_.identity]]
15791      *  The iteratees to invoke.
15792      * @returns {Function} Returns the new function.
15793      * @example
15794      *
15795      * var func = _.over([Math.max, Math.min]);
15796      *
15797      * func(1, 2, 3, 4);
15798      * // => [4, 1]
15799      */
15800     var over = createOver(arrayMap);
15801
15802     /**
15803      * Creates a function that checks if **all** of the `predicates` return
15804      * truthy when invoked with the arguments it receives.
15805      *
15806      * @static
15807      * @memberOf _
15808      * @since 4.0.0
15809      * @category Util
15810      * @param {...(Function|Function[])} [predicates=[_.identity]]
15811      *  The predicates to check.
15812      * @returns {Function} Returns the new function.
15813      * @example
15814      *
15815      * var func = _.overEvery([Boolean, isFinite]);
15816      *
15817      * func('1');
15818      * // => true
15819      *
15820      * func(null);
15821      * // => false
15822      *
15823      * func(NaN);
15824      * // => false
15825      */
15826     var overEvery = createOver(arrayEvery);
15827
15828     /**
15829      * Creates a function that checks if **any** of the `predicates` return
15830      * truthy when invoked with the arguments it receives.
15831      *
15832      * @static
15833      * @memberOf _
15834      * @since 4.0.0
15835      * @category Util
15836      * @param {...(Function|Function[])} [predicates=[_.identity]]
15837      *  The predicates to check.
15838      * @returns {Function} Returns the new function.
15839      * @example
15840      *
15841      * var func = _.overSome([Boolean, isFinite]);
15842      *
15843      * func('1');
15844      * // => true
15845      *
15846      * func(null);
15847      * // => true
15848      *
15849      * func(NaN);
15850      * // => false
15851      */
15852     var overSome = createOver(arraySome);
15853
15854     /**
15855      * Creates a function that returns the value at `path` of a given object.
15856      *
15857      * @static
15858      * @memberOf _
15859      * @since 2.4.0
15860      * @category Util
15861      * @param {Array|string} path The path of the property to get.
15862      * @returns {Function} Returns the new accessor function.
15863      * @example
15864      *
15865      * var objects = [
15866      *   { 'a': { 'b': 2 } },
15867      *   { 'a': { 'b': 1 } }
15868      * ];
15869      *
15870      * _.map(objects, _.property('a.b'));
15871      * // => [2, 1]
15872      *
15873      * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15874      * // => [1, 2]
15875      */
15876     function property(path) {
15877       return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15878     }
15879
15880     /**
15881      * The opposite of `_.property`; this method creates a function that returns
15882      * the value at a given path of `object`.
15883      *
15884      * @static
15885      * @memberOf _
15886      * @since 3.0.0
15887      * @category Util
15888      * @param {Object} object The object to query.
15889      * @returns {Function} Returns the new accessor function.
15890      * @example
15891      *
15892      * var array = [0, 1, 2],
15893      *     object = { 'a': array, 'b': array, 'c': array };
15894      *
15895      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15896      * // => [2, 0]
15897      *
15898      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15899      * // => [2, 0]
15900      */
15901     function propertyOf(object) {
15902       return function(path) {
15903         return object == null ? undefined : baseGet(object, path);
15904       };
15905     }
15906
15907     /**
15908      * Creates an array of numbers (positive and/or negative) progressing from
15909      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15910      * `start` is specified without an `end` or `step`. If `end` is not specified,
15911      * it's set to `start` with `start` then set to `0`.
15912      *
15913      * **Note:** JavaScript follows the IEEE-754 standard for resolving
15914      * floating-point values which can produce unexpected results.
15915      *
15916      * @static
15917      * @since 0.1.0
15918      * @memberOf _
15919      * @category Util
15920      * @param {number} [start=0] The start of the range.
15921      * @param {number} end The end of the range.
15922      * @param {number} [step=1] The value to increment or decrement by.
15923      * @returns {Array} Returns the range of numbers.
15924      * @see _.inRange, _.rangeRight
15925      * @example
15926      *
15927      * _.range(4);
15928      * // => [0, 1, 2, 3]
15929      *
15930      * _.range(-4);
15931      * // => [0, -1, -2, -3]
15932      *
15933      * _.range(1, 5);
15934      * // => [1, 2, 3, 4]
15935      *
15936      * _.range(0, 20, 5);
15937      * // => [0, 5, 10, 15]
15938      *
15939      * _.range(0, -4, -1);
15940      * // => [0, -1, -2, -3]
15941      *
15942      * _.range(1, 4, 0);
15943      * // => [1, 1, 1]
15944      *
15945      * _.range(0);
15946      * // => []
15947      */
15948     var range = createRange();
15949
15950     /**
15951      * This method is like `_.range` except that it populates values in
15952      * descending order.
15953      *
15954      * @static
15955      * @memberOf _
15956      * @since 4.0.0
15957      * @category Util
15958      * @param {number} [start=0] The start of the range.
15959      * @param {number} end The end of the range.
15960      * @param {number} [step=1] The value to increment or decrement by.
15961      * @returns {Array} Returns the range of numbers.
15962      * @see _.inRange, _.range
15963      * @example
15964      *
15965      * _.rangeRight(4);
15966      * // => [3, 2, 1, 0]
15967      *
15968      * _.rangeRight(-4);
15969      * // => [-3, -2, -1, 0]
15970      *
15971      * _.rangeRight(1, 5);
15972      * // => [4, 3, 2, 1]
15973      *
15974      * _.rangeRight(0, 20, 5);
15975      * // => [15, 10, 5, 0]
15976      *
15977      * _.rangeRight(0, -4, -1);
15978      * // => [-3, -2, -1, 0]
15979      *
15980      * _.rangeRight(1, 4, 0);
15981      * // => [1, 1, 1]
15982      *
15983      * _.rangeRight(0);
15984      * // => []
15985      */
15986     var rangeRight = createRange(true);
15987
15988     /**
15989      * This method returns a new empty array.
15990      *
15991      * @static
15992      * @memberOf _
15993      * @since 4.13.0
15994      * @category Util
15995      * @returns {Array} Returns the new empty array.
15996      * @example
15997      *
15998      * var arrays = _.times(2, _.stubArray);
15999      *
16000      * console.log(arrays);
16001      * // => [[], []]
16002      *
16003      * console.log(arrays[0] === arrays[1]);
16004      * // => false
16005      */
16006     function stubArray() {
16007       return [];
16008     }
16009
16010     /**
16011      * This method returns `false`.
16012      *
16013      * @static
16014      * @memberOf _
16015      * @since 4.13.0
16016      * @category Util
16017      * @returns {boolean} Returns `false`.
16018      * @example
16019      *
16020      * _.times(2, _.stubFalse);
16021      * // => [false, false]
16022      */
16023     function stubFalse() {
16024       return false;
16025     }
16026
16027     /**
16028      * This method returns a new empty object.
16029      *
16030      * @static
16031      * @memberOf _
16032      * @since 4.13.0
16033      * @category Util
16034      * @returns {Object} Returns the new empty object.
16035      * @example
16036      *
16037      * var objects = _.times(2, _.stubObject);
16038      *
16039      * console.log(objects);
16040      * // => [{}, {}]
16041      *
16042      * console.log(objects[0] === objects[1]);
16043      * // => false
16044      */
16045     function stubObject() {
16046       return {};
16047     }
16048
16049     /**
16050      * This method returns an empty string.
16051      *
16052      * @static
16053      * @memberOf _
16054      * @since 4.13.0
16055      * @category Util
16056      * @returns {string} Returns the empty string.
16057      * @example
16058      *
16059      * _.times(2, _.stubString);
16060      * // => ['', '']
16061      */
16062     function stubString() {
16063       return '';
16064     }
16065
16066     /**
16067      * This method returns `true`.
16068      *
16069      * @static
16070      * @memberOf _
16071      * @since 4.13.0
16072      * @category Util
16073      * @returns {boolean} Returns `true`.
16074      * @example
16075      *
16076      * _.times(2, _.stubTrue);
16077      * // => [true, true]
16078      */
16079     function stubTrue() {
16080       return true;
16081     }
16082
16083     /**
16084      * Invokes the iteratee `n` times, returning an array of the results of
16085      * each invocation. The iteratee is invoked with one argument; (index).
16086      *
16087      * @static
16088      * @since 0.1.0
16089      * @memberOf _
16090      * @category Util
16091      * @param {number} n The number of times to invoke `iteratee`.
16092      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
16093      * @returns {Array} Returns the array of results.
16094      * @example
16095      *
16096      * _.times(3, String);
16097      * // => ['0', '1', '2']
16098      *
16099      *  _.times(4, _.constant(0));
16100      * // => [0, 0, 0, 0]
16101      */
16102     function times(n, iteratee) {
16103       n = toInteger(n);
16104       if (n < 1 || n > MAX_SAFE_INTEGER) {
16105         return [];
16106       }
16107       var index = MAX_ARRAY_LENGTH,
16108           length = nativeMin(n, MAX_ARRAY_LENGTH);
16109
16110       iteratee = getIteratee(iteratee);
16111       n -= MAX_ARRAY_LENGTH;
16112
16113       var result = baseTimes(length, iteratee);
16114       while (++index < n) {
16115         iteratee(index);
16116       }
16117       return result;
16118     }
16119
16120     /**
16121      * Converts `value` to a property path array.
16122      *
16123      * @static
16124      * @memberOf _
16125      * @since 4.0.0
16126      * @category Util
16127      * @param {*} value The value to convert.
16128      * @returns {Array} Returns the new property path array.
16129      * @example
16130      *
16131      * _.toPath('a.b.c');
16132      * // => ['a', 'b', 'c']
16133      *
16134      * _.toPath('a[0].b.c');
16135      * // => ['a', '0', 'b', 'c']
16136      */
16137     function toPath(value) {
16138       if (isArray(value)) {
16139         return arrayMap(value, toKey);
16140       }
16141       return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
16142     }
16143
16144     /**
16145      * Generates a unique ID. If `prefix` is given, the ID is appended to it.
16146      *
16147      * @static
16148      * @since 0.1.0
16149      * @memberOf _
16150      * @category Util
16151      * @param {string} [prefix=''] The value to prefix the ID with.
16152      * @returns {string} Returns the unique ID.
16153      * @example
16154      *
16155      * _.uniqueId('contact_');
16156      * // => 'contact_104'
16157      *
16158      * _.uniqueId();
16159      * // => '105'
16160      */
16161     function uniqueId(prefix) {
16162       var id = ++idCounter;
16163       return toString(prefix) + id;
16164     }
16165
16166     /*------------------------------------------------------------------------*/
16167
16168     /**
16169      * Adds two numbers.
16170      *
16171      * @static
16172      * @memberOf _
16173      * @since 3.4.0
16174      * @category Math
16175      * @param {number} augend The first number in an addition.
16176      * @param {number} addend The second number in an addition.
16177      * @returns {number} Returns the total.
16178      * @example
16179      *
16180      * _.add(6, 4);
16181      * // => 10
16182      */
16183     var add = createMathOperation(function(augend, addend) {
16184       return augend + addend;
16185     }, 0);
16186
16187     /**
16188      * Computes `number` rounded up to `precision`.
16189      *
16190      * @static
16191      * @memberOf _
16192      * @since 3.10.0
16193      * @category Math
16194      * @param {number} number The number to round up.
16195      * @param {number} [precision=0] The precision to round up to.
16196      * @returns {number} Returns the rounded up number.
16197      * @example
16198      *
16199      * _.ceil(4.006);
16200      * // => 5
16201      *
16202      * _.ceil(6.004, 2);
16203      * // => 6.01
16204      *
16205      * _.ceil(6040, -2);
16206      * // => 6100
16207      */
16208     var ceil = createRound('ceil');
16209
16210     /**
16211      * Divide two numbers.
16212      *
16213      * @static
16214      * @memberOf _
16215      * @since 4.7.0
16216      * @category Math
16217      * @param {number} dividend The first number in a division.
16218      * @param {number} divisor The second number in a division.
16219      * @returns {number} Returns the quotient.
16220      * @example
16221      *
16222      * _.divide(6, 4);
16223      * // => 1.5
16224      */
16225     var divide = createMathOperation(function(dividend, divisor) {
16226       return dividend / divisor;
16227     }, 1);
16228
16229     /**
16230      * Computes `number` rounded down to `precision`.
16231      *
16232      * @static
16233      * @memberOf _
16234      * @since 3.10.0
16235      * @category Math
16236      * @param {number} number The number to round down.
16237      * @param {number} [precision=0] The precision to round down to.
16238      * @returns {number} Returns the rounded down number.
16239      * @example
16240      *
16241      * _.floor(4.006);
16242      * // => 4
16243      *
16244      * _.floor(0.046, 2);
16245      * // => 0.04
16246      *
16247      * _.floor(4060, -2);
16248      * // => 4000
16249      */
16250     var floor = createRound('floor');
16251
16252     /**
16253      * Computes the maximum value of `array`. If `array` is empty or falsey,
16254      * `undefined` is returned.
16255      *
16256      * @static
16257      * @since 0.1.0
16258      * @memberOf _
16259      * @category Math
16260      * @param {Array} array The array to iterate over.
16261      * @returns {*} Returns the maximum value.
16262      * @example
16263      *
16264      * _.max([4, 2, 8, 6]);
16265      * // => 8
16266      *
16267      * _.max([]);
16268      * // => undefined
16269      */
16270     function max(array) {
16271       return (array && array.length)
16272         ? baseExtremum(array, identity, baseGt)
16273         : undefined;
16274     }
16275
16276     /**
16277      * This method is like `_.max` except that it accepts `iteratee` which is
16278      * invoked for each element in `array` to generate the criterion by which
16279      * the value is ranked. The iteratee is invoked with one argument: (value).
16280      *
16281      * @static
16282      * @memberOf _
16283      * @since 4.0.0
16284      * @category Math
16285      * @param {Array} array The array to iterate over.
16286      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16287      * @returns {*} Returns the maximum value.
16288      * @example
16289      *
16290      * var objects = [{ 'n': 1 }, { 'n': 2 }];
16291      *
16292      * _.maxBy(objects, function(o) { return o.n; });
16293      * // => { 'n': 2 }
16294      *
16295      * // The `_.property` iteratee shorthand.
16296      * _.maxBy(objects, 'n');
16297      * // => { 'n': 2 }
16298      */
16299     function maxBy(array, iteratee) {
16300       return (array && array.length)
16301         ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
16302         : undefined;
16303     }
16304
16305     /**
16306      * Computes the mean of the values in `array`.
16307      *
16308      * @static
16309      * @memberOf _
16310      * @since 4.0.0
16311      * @category Math
16312      * @param {Array} array The array to iterate over.
16313      * @returns {number} Returns the mean.
16314      * @example
16315      *
16316      * _.mean([4, 2, 8, 6]);
16317      * // => 5
16318      */
16319     function mean(array) {
16320       return baseMean(array, identity);
16321     }
16322
16323     /**
16324      * This method is like `_.mean` except that it accepts `iteratee` which is
16325      * invoked for each element in `array` to generate the value to be averaged.
16326      * The iteratee is invoked with one argument: (value).
16327      *
16328      * @static
16329      * @memberOf _
16330      * @since 4.7.0
16331      * @category Math
16332      * @param {Array} array The array to iterate over.
16333      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16334      * @returns {number} Returns the mean.
16335      * @example
16336      *
16337      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16338      *
16339      * _.meanBy(objects, function(o) { return o.n; });
16340      * // => 5
16341      *
16342      * // The `_.property` iteratee shorthand.
16343      * _.meanBy(objects, 'n');
16344      * // => 5
16345      */
16346     function meanBy(array, iteratee) {
16347       return baseMean(array, getIteratee(iteratee, 2));
16348     }
16349
16350     /**
16351      * Computes the minimum value of `array`. If `array` is empty or falsey,
16352      * `undefined` is returned.
16353      *
16354      * @static
16355      * @since 0.1.0
16356      * @memberOf _
16357      * @category Math
16358      * @param {Array} array The array to iterate over.
16359      * @returns {*} Returns the minimum value.
16360      * @example
16361      *
16362      * _.min([4, 2, 8, 6]);
16363      * // => 2
16364      *
16365      * _.min([]);
16366      * // => undefined
16367      */
16368     function min(array) {
16369       return (array && array.length)
16370         ? baseExtremum(array, identity, baseLt)
16371         : undefined;
16372     }
16373
16374     /**
16375      * This method is like `_.min` except that it accepts `iteratee` which is
16376      * invoked for each element in `array` to generate the criterion by which
16377      * the value is ranked. The iteratee is invoked with one argument: (value).
16378      *
16379      * @static
16380      * @memberOf _
16381      * @since 4.0.0
16382      * @category Math
16383      * @param {Array} array The array to iterate over.
16384      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16385      * @returns {*} Returns the minimum value.
16386      * @example
16387      *
16388      * var objects = [{ 'n': 1 }, { 'n': 2 }];
16389      *
16390      * _.minBy(objects, function(o) { return o.n; });
16391      * // => { 'n': 1 }
16392      *
16393      * // The `_.property` iteratee shorthand.
16394      * _.minBy(objects, 'n');
16395      * // => { 'n': 1 }
16396      */
16397     function minBy(array, iteratee) {
16398       return (array && array.length)
16399         ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
16400         : undefined;
16401     }
16402
16403     /**
16404      * Multiply two numbers.
16405      *
16406      * @static
16407      * @memberOf _
16408      * @since 4.7.0
16409      * @category Math
16410      * @param {number} multiplier The first number in a multiplication.
16411      * @param {number} multiplicand The second number in a multiplication.
16412      * @returns {number} Returns the product.
16413      * @example
16414      *
16415      * _.multiply(6, 4);
16416      * // => 24
16417      */
16418     var multiply = createMathOperation(function(multiplier, multiplicand) {
16419       return multiplier * multiplicand;
16420     }, 1);
16421
16422     /**
16423      * Computes `number` rounded to `precision`.
16424      *
16425      * @static
16426      * @memberOf _
16427      * @since 3.10.0
16428      * @category Math
16429      * @param {number} number The number to round.
16430      * @param {number} [precision=0] The precision to round to.
16431      * @returns {number} Returns the rounded number.
16432      * @example
16433      *
16434      * _.round(4.006);
16435      * // => 4
16436      *
16437      * _.round(4.006, 2);
16438      * // => 4.01
16439      *
16440      * _.round(4060, -2);
16441      * // => 4100
16442      */
16443     var round = createRound('round');
16444
16445     /**
16446      * Subtract two numbers.
16447      *
16448      * @static
16449      * @memberOf _
16450      * @since 4.0.0
16451      * @category Math
16452      * @param {number} minuend The first number in a subtraction.
16453      * @param {number} subtrahend The second number in a subtraction.
16454      * @returns {number} Returns the difference.
16455      * @example
16456      *
16457      * _.subtract(6, 4);
16458      * // => 2
16459      */
16460     var subtract = createMathOperation(function(minuend, subtrahend) {
16461       return minuend - subtrahend;
16462     }, 0);
16463
16464     /**
16465      * Computes the sum of the values in `array`.
16466      *
16467      * @static
16468      * @memberOf _
16469      * @since 3.4.0
16470      * @category Math
16471      * @param {Array} array The array to iterate over.
16472      * @returns {number} Returns the sum.
16473      * @example
16474      *
16475      * _.sum([4, 2, 8, 6]);
16476      * // => 20
16477      */
16478     function sum(array) {
16479       return (array && array.length)
16480         ? baseSum(array, identity)
16481         : 0;
16482     }
16483
16484     /**
16485      * This method is like `_.sum` except that it accepts `iteratee` which is
16486      * invoked for each element in `array` to generate the value to be summed.
16487      * The iteratee is invoked with one argument: (value).
16488      *
16489      * @static
16490      * @memberOf _
16491      * @since 4.0.0
16492      * @category Math
16493      * @param {Array} array The array to iterate over.
16494      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16495      * @returns {number} Returns the sum.
16496      * @example
16497      *
16498      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16499      *
16500      * _.sumBy(objects, function(o) { return o.n; });
16501      * // => 20
16502      *
16503      * // The `_.property` iteratee shorthand.
16504      * _.sumBy(objects, 'n');
16505      * // => 20
16506      */
16507     function sumBy(array, iteratee) {
16508       return (array && array.length)
16509         ? baseSum(array, getIteratee(iteratee, 2))
16510         : 0;
16511     }
16512
16513     /*------------------------------------------------------------------------*/
16514
16515     // Add methods that return wrapped values in chain sequences.
16516     lodash.after = after;
16517     lodash.ary = ary;
16518     lodash.assign = assign;
16519     lodash.assignIn = assignIn;
16520     lodash.assignInWith = assignInWith;
16521     lodash.assignWith = assignWith;
16522     lodash.at = at;
16523     lodash.before = before;
16524     lodash.bind = bind;
16525     lodash.bindAll = bindAll;
16526     lodash.bindKey = bindKey;
16527     lodash.castArray = castArray;
16528     lodash.chain = chain;
16529     lodash.chunk = chunk;
16530     lodash.compact = compact;
16531     lodash.concat = concat;
16532     lodash.cond = cond;
16533     lodash.conforms = conforms;
16534     lodash.constant = constant;
16535     lodash.countBy = countBy;
16536     lodash.create = create;
16537     lodash.curry = curry;
16538     lodash.curryRight = curryRight;
16539     lodash.debounce = debounce;
16540     lodash.defaults = defaults;
16541     lodash.defaultsDeep = defaultsDeep;
16542     lodash.defer = defer;
16543     lodash.delay = delay;
16544     lodash.difference = difference;
16545     lodash.differenceBy = differenceBy;
16546     lodash.differenceWith = differenceWith;
16547     lodash.drop = drop;
16548     lodash.dropRight = dropRight;
16549     lodash.dropRightWhile = dropRightWhile;
16550     lodash.dropWhile = dropWhile;
16551     lodash.fill = fill;
16552     lodash.filter = filter;
16553     lodash.flatMap = flatMap;
16554     lodash.flatMapDeep = flatMapDeep;
16555     lodash.flatMapDepth = flatMapDepth;
16556     lodash.flatten = flatten;
16557     lodash.flattenDeep = flattenDeep;
16558     lodash.flattenDepth = flattenDepth;
16559     lodash.flip = flip;
16560     lodash.flow = flow;
16561     lodash.flowRight = flowRight;
16562     lodash.fromPairs = fromPairs;
16563     lodash.functions = functions;
16564     lodash.functionsIn = functionsIn;
16565     lodash.groupBy = groupBy;
16566     lodash.initial = initial;
16567     lodash.intersection = intersection;
16568     lodash.intersectionBy = intersectionBy;
16569     lodash.intersectionWith = intersectionWith;
16570     lodash.invert = invert;
16571     lodash.invertBy = invertBy;
16572     lodash.invokeMap = invokeMap;
16573     lodash.iteratee = iteratee;
16574     lodash.keyBy = keyBy;
16575     lodash.keys = keys;
16576     lodash.keysIn = keysIn;
16577     lodash.map = map;
16578     lodash.mapKeys = mapKeys;
16579     lodash.mapValues = mapValues;
16580     lodash.matches = matches;
16581     lodash.matchesProperty = matchesProperty;
16582     lodash.memoize = memoize;
16583     lodash.merge = merge;
16584     lodash.mergeWith = mergeWith;
16585     lodash.method = method;
16586     lodash.methodOf = methodOf;
16587     lodash.mixin = mixin;
16588     lodash.negate = negate;
16589     lodash.nthArg = nthArg;
16590     lodash.omit = omit;
16591     lodash.omitBy = omitBy;
16592     lodash.once = once;
16593     lodash.orderBy = orderBy;
16594     lodash.over = over;
16595     lodash.overArgs = overArgs;
16596     lodash.overEvery = overEvery;
16597     lodash.overSome = overSome;
16598     lodash.partial = partial;
16599     lodash.partialRight = partialRight;
16600     lodash.partition = partition;
16601     lodash.pick = pick;
16602     lodash.pickBy = pickBy;
16603     lodash.property = property;
16604     lodash.propertyOf = propertyOf;
16605     lodash.pull = pull;
16606     lodash.pullAll = pullAll;
16607     lodash.pullAllBy = pullAllBy;
16608     lodash.pullAllWith = pullAllWith;
16609     lodash.pullAt = pullAt;
16610     lodash.range = range;
16611     lodash.rangeRight = rangeRight;
16612     lodash.rearg = rearg;
16613     lodash.reject = reject;
16614     lodash.remove = remove;
16615     lodash.rest = rest;
16616     lodash.reverse = reverse;
16617     lodash.sampleSize = sampleSize;
16618     lodash.set = set;
16619     lodash.setWith = setWith;
16620     lodash.shuffle = shuffle;
16621     lodash.slice = slice;
16622     lodash.sortBy = sortBy;
16623     lodash.sortedUniq = sortedUniq;
16624     lodash.sortedUniqBy = sortedUniqBy;
16625     lodash.split = split;
16626     lodash.spread = spread;
16627     lodash.tail = tail;
16628     lodash.take = take;
16629     lodash.takeRight = takeRight;
16630     lodash.takeRightWhile = takeRightWhile;
16631     lodash.takeWhile = takeWhile;
16632     lodash.tap = tap;
16633     lodash.throttle = throttle;
16634     lodash.thru = thru;
16635     lodash.toArray = toArray;
16636     lodash.toPairs = toPairs;
16637     lodash.toPairsIn = toPairsIn;
16638     lodash.toPath = toPath;
16639     lodash.toPlainObject = toPlainObject;
16640     lodash.transform = transform;
16641     lodash.unary = unary;
16642     lodash.union = union;
16643     lodash.unionBy = unionBy;
16644     lodash.unionWith = unionWith;
16645     lodash.uniq = uniq;
16646     lodash.uniqBy = uniqBy;
16647     lodash.uniqWith = uniqWith;
16648     lodash.unset = unset;
16649     lodash.unzip = unzip;
16650     lodash.unzipWith = unzipWith;
16651     lodash.update = update;
16652     lodash.updateWith = updateWith;
16653     lodash.values = values;
16654     lodash.valuesIn = valuesIn;
16655     lodash.without = without;
16656     lodash.words = words;
16657     lodash.wrap = wrap;
16658     lodash.xor = xor;
16659     lodash.xorBy = xorBy;
16660     lodash.xorWith = xorWith;
16661     lodash.zip = zip;
16662     lodash.zipObject = zipObject;
16663     lodash.zipObjectDeep = zipObjectDeep;
16664     lodash.zipWith = zipWith;
16665
16666     // Add aliases.
16667     lodash.entries = toPairs;
16668     lodash.entriesIn = toPairsIn;
16669     lodash.extend = assignIn;
16670     lodash.extendWith = assignInWith;
16671
16672     // Add methods to `lodash.prototype`.
16673     mixin(lodash, lodash);
16674
16675     /*------------------------------------------------------------------------*/
16676
16677     // Add methods that return unwrapped values in chain sequences.
16678     lodash.add = add;
16679     lodash.attempt = attempt;
16680     lodash.camelCase = camelCase;
16681     lodash.capitalize = capitalize;
16682     lodash.ceil = ceil;
16683     lodash.clamp = clamp;
16684     lodash.clone = clone;
16685     lodash.cloneDeep = cloneDeep;
16686     lodash.cloneDeepWith = cloneDeepWith;
16687     lodash.cloneWith = cloneWith;
16688     lodash.conformsTo = conformsTo;
16689     lodash.deburr = deburr;
16690     lodash.defaultTo = defaultTo;
16691     lodash.divide = divide;
16692     lodash.endsWith = endsWith;
16693     lodash.eq = eq;
16694     lodash.escape = escape;
16695     lodash.escapeRegExp = escapeRegExp;
16696     lodash.every = every;
16697     lodash.find = find;
16698     lodash.findIndex = findIndex;
16699     lodash.findKey = findKey;
16700     lodash.findLast = findLast;
16701     lodash.findLastIndex = findLastIndex;
16702     lodash.findLastKey = findLastKey;
16703     lodash.floor = floor;
16704     lodash.forEach = forEach;
16705     lodash.forEachRight = forEachRight;
16706     lodash.forIn = forIn;
16707     lodash.forInRight = forInRight;
16708     lodash.forOwn = forOwn;
16709     lodash.forOwnRight = forOwnRight;
16710     lodash.get = get;
16711     lodash.gt = gt;
16712     lodash.gte = gte;
16713     lodash.has = has;
16714     lodash.hasIn = hasIn;
16715     lodash.head = head;
16716     lodash.identity = identity;
16717     lodash.includes = includes;
16718     lodash.indexOf = indexOf;
16719     lodash.inRange = inRange;
16720     lodash.invoke = invoke;
16721     lodash.isArguments = isArguments;
16722     lodash.isArray = isArray;
16723     lodash.isArrayBuffer = isArrayBuffer;
16724     lodash.isArrayLike = isArrayLike;
16725     lodash.isArrayLikeObject = isArrayLikeObject;
16726     lodash.isBoolean = isBoolean;
16727     lodash.isBuffer = isBuffer;
16728     lodash.isDate = isDate;
16729     lodash.isElement = isElement;
16730     lodash.isEmpty = isEmpty;
16731     lodash.isEqual = isEqual;
16732     lodash.isEqualWith = isEqualWith;
16733     lodash.isError = isError;
16734     lodash.isFinite = isFinite;
16735     lodash.isFunction = isFunction;
16736     lodash.isInteger = isInteger;
16737     lodash.isLength = isLength;
16738     lodash.isMap = isMap;
16739     lodash.isMatch = isMatch;
16740     lodash.isMatchWith = isMatchWith;
16741     lodash.isNaN = isNaN;
16742     lodash.isNative = isNative;
16743     lodash.isNil = isNil;
16744     lodash.isNull = isNull;
16745     lodash.isNumber = isNumber;
16746     lodash.isObject = isObject;
16747     lodash.isObjectLike = isObjectLike;
16748     lodash.isPlainObject = isPlainObject;
16749     lodash.isRegExp = isRegExp;
16750     lodash.isSafeInteger = isSafeInteger;
16751     lodash.isSet = isSet;
16752     lodash.isString = isString;
16753     lodash.isSymbol = isSymbol;
16754     lodash.isTypedArray = isTypedArray;
16755     lodash.isUndefined = isUndefined;
16756     lodash.isWeakMap = isWeakMap;
16757     lodash.isWeakSet = isWeakSet;
16758     lodash.join = join;
16759     lodash.kebabCase = kebabCase;
16760     lodash.last = last;
16761     lodash.lastIndexOf = lastIndexOf;
16762     lodash.lowerCase = lowerCase;
16763     lodash.lowerFirst = lowerFirst;
16764     lodash.lt = lt;
16765     lodash.lte = lte;
16766     lodash.max = max;
16767     lodash.maxBy = maxBy;
16768     lodash.mean = mean;
16769     lodash.meanBy = meanBy;
16770     lodash.min = min;
16771     lodash.minBy = minBy;
16772     lodash.stubArray = stubArray;
16773     lodash.stubFalse = stubFalse;
16774     lodash.stubObject = stubObject;
16775     lodash.stubString = stubString;
16776     lodash.stubTrue = stubTrue;
16777     lodash.multiply = multiply;
16778     lodash.nth = nth;
16779     lodash.noConflict = noConflict;
16780     lodash.noop = noop;
16781     lodash.now = now;
16782     lodash.pad = pad;
16783     lodash.padEnd = padEnd;
16784     lodash.padStart = padStart;
16785     lodash.parseInt = parseInt;
16786     lodash.random = random;
16787     lodash.reduce = reduce;
16788     lodash.reduceRight = reduceRight;
16789     lodash.repeat = repeat;
16790     lodash.replace = replace;
16791     lodash.result = result;
16792     lodash.round = round;
16793     lodash.runInContext = runInContext;
16794     lodash.sample = sample;
16795     lodash.size = size;
16796     lodash.snakeCase = snakeCase;
16797     lodash.some = some;
16798     lodash.sortedIndex = sortedIndex;
16799     lodash.sortedIndexBy = sortedIndexBy;
16800     lodash.sortedIndexOf = sortedIndexOf;
16801     lodash.sortedLastIndex = sortedLastIndex;
16802     lodash.sortedLastIndexBy = sortedLastIndexBy;
16803     lodash.sortedLastIndexOf = sortedLastIndexOf;
16804     lodash.startCase = startCase;
16805     lodash.startsWith = startsWith;
16806     lodash.subtract = subtract;
16807     lodash.sum = sum;
16808     lodash.sumBy = sumBy;
16809     lodash.template = template;
16810     lodash.times = times;
16811     lodash.toFinite = toFinite;
16812     lodash.toInteger = toInteger;
16813     lodash.toLength = toLength;
16814     lodash.toLower = toLower;
16815     lodash.toNumber = toNumber;
16816     lodash.toSafeInteger = toSafeInteger;
16817     lodash.toString = toString;
16818     lodash.toUpper = toUpper;
16819     lodash.trim = trim;
16820     lodash.trimEnd = trimEnd;
16821     lodash.trimStart = trimStart;
16822     lodash.truncate = truncate;
16823     lodash.unescape = unescape;
16824     lodash.uniqueId = uniqueId;
16825     lodash.upperCase = upperCase;
16826     lodash.upperFirst = upperFirst;
16827
16828     // Add aliases.
16829     lodash.each = forEach;
16830     lodash.eachRight = forEachRight;
16831     lodash.first = head;
16832
16833     mixin(lodash, (function() {
16834       var source = {};
16835       baseForOwn(lodash, function(func, methodName) {
16836         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16837           source[methodName] = func;
16838         }
16839       });
16840       return source;
16841     }()), { 'chain': false });
16842
16843     /*------------------------------------------------------------------------*/
16844
16845     /**
16846      * The semantic version number.
16847      *
16848      * @static
16849      * @memberOf _
16850      * @type {string}
16851      */
16852     lodash.VERSION = VERSION;
16853
16854     // Assign default placeholders.
16855     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16856       lodash[methodName].placeholder = lodash;
16857     });
16858
16859     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16860     arrayEach(['drop', 'take'], function(methodName, index) {
16861       LazyWrapper.prototype[methodName] = function(n) {
16862         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16863
16864         var result = (this.__filtered__ && !index)
16865           ? new LazyWrapper(this)
16866           : this.clone();
16867
16868         if (result.__filtered__) {
16869           result.__takeCount__ = nativeMin(n, result.__takeCount__);
16870         } else {
16871           result.__views__.push({
16872             'size': nativeMin(n, MAX_ARRAY_LENGTH),
16873             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16874           });
16875         }
16876         return result;
16877       };
16878
16879       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16880         return this.reverse()[methodName](n).reverse();
16881       };
16882     });
16883
16884     // Add `LazyWrapper` methods that accept an `iteratee` value.
16885     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16886       var type = index + 1,
16887           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16888
16889       LazyWrapper.prototype[methodName] = function(iteratee) {
16890         var result = this.clone();
16891         result.__iteratees__.push({
16892           'iteratee': getIteratee(iteratee, 3),
16893           'type': type
16894         });
16895         result.__filtered__ = result.__filtered__ || isFilter;
16896         return result;
16897       };
16898     });
16899
16900     // Add `LazyWrapper` methods for `_.head` and `_.last`.
16901     arrayEach(['head', 'last'], function(methodName, index) {
16902       var takeName = 'take' + (index ? 'Right' : '');
16903
16904       LazyWrapper.prototype[methodName] = function() {
16905         return this[takeName](1).value()[0];
16906       };
16907     });
16908
16909     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
16910     arrayEach(['initial', 'tail'], function(methodName, index) {
16911       var dropName = 'drop' + (index ? '' : 'Right');
16912
16913       LazyWrapper.prototype[methodName] = function() {
16914         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
16915       };
16916     });
16917
16918     LazyWrapper.prototype.compact = function() {
16919       return this.filter(identity);
16920     };
16921
16922     LazyWrapper.prototype.find = function(predicate) {
16923       return this.filter(predicate).head();
16924     };
16925
16926     LazyWrapper.prototype.findLast = function(predicate) {
16927       return this.reverse().find(predicate);
16928     };
16929
16930     LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
16931       if (typeof path == 'function') {
16932         return new LazyWrapper(this);
16933       }
16934       return this.map(function(value) {
16935         return baseInvoke(value, path, args);
16936       });
16937     });
16938
16939     LazyWrapper.prototype.reject = function(predicate) {
16940       return this.filter(negate(getIteratee(predicate)));
16941     };
16942
16943     LazyWrapper.prototype.slice = function(start, end) {
16944       start = toInteger(start);
16945
16946       var result = this;
16947       if (result.__filtered__ && (start > 0 || end < 0)) {
16948         return new LazyWrapper(result);
16949       }
16950       if (start < 0) {
16951         result = result.takeRight(-start);
16952       } else if (start) {
16953         result = result.drop(start);
16954       }
16955       if (end !== undefined) {
16956         end = toInteger(end);
16957         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16958       }
16959       return result;
16960     };
16961
16962     LazyWrapper.prototype.takeRightWhile = function(predicate) {
16963       return this.reverse().takeWhile(predicate).reverse();
16964     };
16965
16966     LazyWrapper.prototype.toArray = function() {
16967       return this.take(MAX_ARRAY_LENGTH);
16968     };
16969
16970     // Add `LazyWrapper` methods to `lodash.prototype`.
16971     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16972       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16973           isTaker = /^(?:head|last)$/.test(methodName),
16974           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16975           retUnwrapped = isTaker || /^find/.test(methodName);
16976
16977       if (!lodashFunc) {
16978         return;
16979       }
16980       lodash.prototype[methodName] = function() {
16981         var value = this.__wrapped__,
16982             args = isTaker ? [1] : arguments,
16983             isLazy = value instanceof LazyWrapper,
16984             iteratee = args[0],
16985             useLazy = isLazy || isArray(value);
16986
16987         var interceptor = function(value) {
16988           var result = lodashFunc.apply(lodash, arrayPush([value], args));
16989           return (isTaker && chainAll) ? result[0] : result;
16990         };
16991
16992         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16993           // Avoid lazy use if the iteratee has a "length" value other than `1`.
16994           isLazy = useLazy = false;
16995         }
16996         var chainAll = this.__chain__,
16997             isHybrid = !!this.__actions__.length,
16998             isUnwrapped = retUnwrapped && !chainAll,
16999             onlyLazy = isLazy && !isHybrid;
17000
17001         if (!retUnwrapped && useLazy) {
17002           value = onlyLazy ? value : new LazyWrapper(this);
17003           var result = func.apply(value, args);
17004           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
17005           return new LodashWrapper(result, chainAll);
17006         }
17007         if (isUnwrapped && onlyLazy) {
17008           return func.apply(this, args);
17009         }
17010         result = this.thru(interceptor);
17011         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
17012       };
17013     });
17014
17015     // Add `Array` methods to `lodash.prototype`.
17016     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
17017       var func = arrayProto[methodName],
17018           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
17019           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
17020
17021       lodash.prototype[methodName] = function() {
17022         var args = arguments;
17023         if (retUnwrapped && !this.__chain__) {
17024           var value = this.value();
17025           return func.apply(isArray(value) ? value : [], args);
17026         }
17027         return this[chainName](function(value) {
17028           return func.apply(isArray(value) ? value : [], args);
17029         });
17030       };
17031     });
17032
17033     // Map minified method names to their real names.
17034     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17035       var lodashFunc = lodash[methodName];
17036       if (lodashFunc) {
17037         var key = (lodashFunc.name + ''),
17038             names = realNames[key] || (realNames[key] = []);
17039
17040         names.push({ 'name': methodName, 'func': lodashFunc });
17041       }
17042     });
17043
17044     realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
17045       'name': 'wrapper',
17046       'func': undefined
17047     }];
17048
17049     // Add methods to `LazyWrapper`.
17050     LazyWrapper.prototype.clone = lazyClone;
17051     LazyWrapper.prototype.reverse = lazyReverse;
17052     LazyWrapper.prototype.value = lazyValue;
17053
17054     // Add chain sequence methods to the `lodash` wrapper.
17055     lodash.prototype.at = wrapperAt;
17056     lodash.prototype.chain = wrapperChain;
17057     lodash.prototype.commit = wrapperCommit;
17058     lodash.prototype.next = wrapperNext;
17059     lodash.prototype.plant = wrapperPlant;
17060     lodash.prototype.reverse = wrapperReverse;
17061     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
17062
17063     // Add lazy aliases.
17064     lodash.prototype.first = lodash.prototype.head;
17065
17066     if (symIterator) {
17067       lodash.prototype[symIterator] = wrapperToIterator;
17068     }
17069     return lodash;
17070   });
17071
17072   /*--------------------------------------------------------------------------*/
17073
17074   // Export lodash.
17075   var _ = runInContext();
17076
17077   // Some AMD build optimizers, like r.js, check for condition patterns like:
17078   if (typeof undefined == 'function' && typeof undefined.amd == 'object' && undefined.amd) {
17079     // Expose Lodash on the global object to prevent errors when Lodash is
17080     // loaded by a script tag in the presence of an AMD loader.
17081     // See http://requirejs.org/docs/errors.html#mismatch for more details.
17082     // Use `_.noConflict` to remove Lodash from the global object.
17083     root._ = _;
17084
17085     // Define as an anonymous module so, through path mapping, it can be
17086     // referenced as the "underscore" module.
17087     undefined(function() {
17088       return _;
17089     });
17090   }
17091   // Check for `exports` after `define` in case a build optimizer adds it.
17092   else if (freeModule) {
17093     // Export for Node.js.
17094     (freeModule.exports = _)._ = _;
17095     // Export for CommonJS support.
17096     freeExports._ = _;
17097   }
17098   else {
17099     // Export to the global object.
17100     root._ = _;
17101   }
17102 }.call(commonjsGlobal));
17103 });
17104
17105
17106
17107 var lodash$1 = Object.freeze({
17108         default: lodash,
17109         __moduleExports: lodash
17110 });
17111
17112 function osmIsInterestingTag(key) {
17113     return key !== 'attribution' &&
17114         key !== 'created_by' &&
17115         key !== 'source' &&
17116         key !== 'odbl' &&
17117         key.indexOf('tiger:') !== 0;
17118
17119 }
17120
17121
17122 var osmOneWayTags = {
17123     'aerialway': {
17124         'chair_lift': true,
17125         'mixed_lift': true,
17126         't-bar': true,
17127         'j-bar': true,
17128         'platter': true,
17129         'rope_tow': true,
17130         'magic_carpet': true,
17131         'yes': true
17132     },
17133     'highway': {
17134         'motorway': true,
17135         'motorway_link': true
17136     },
17137     'junction': {
17138         'roundabout': true
17139     },
17140     'man_made': {
17141         'piste:halfpipe': true
17142     },
17143     'piste:type': {
17144         'downhill': true,
17145         'sled': true,
17146         'yes': true
17147     },
17148     'waterway': {
17149         'canal': true,
17150         'ditch': true,
17151         'drain': true,
17152         'river': true,
17153         'stream': true
17154     }
17155 };
17156
17157
17158 var osmPavedTags = {
17159     'surface': {
17160         'paved': true,
17161         'asphalt': true,
17162         'concrete': true,
17163         'concrete:lanes': true,
17164         'concrete:plates': true
17165     },
17166     'tracktype': {
17167         'grade1': true
17168     }
17169 };
17170
17171 var dataWikipedia = [
17172     [
17173         "Abkhazian",
17174         "Аҧсшәа",
17175         "ab"
17176     ],
17177     [
17178         "Achinese",
17179         "Acèh",
17180         "ace"
17181     ],
17182     [
17183         "Adyghe",
17184         "адыгабзэ",
17185         "ady"
17186     ],
17187     [
17188         "Afrikaans",
17189         "Afrikaans",
17190         "af"
17191     ],
17192     [
17193         "Akan",
17194         "Akan",
17195         "ak"
17196     ],
17197     [
17198         "Alemannisch",
17199         "Alemannisch",
17200         "als"
17201     ],
17202     [
17203         "Amharic",
17204         "አማርኛ",
17205         "am"
17206     ],
17207     [
17208         "Aragonese",
17209         "aragonés",
17210         "an"
17211     ],
17212     [
17213         "Old English",
17214         "Ænglisc",
17215         "ang"
17216     ],
17217     [
17218         "Arabic",
17219         "العربية",
17220         "ar"
17221     ],
17222     [
17223         "Aramaic",
17224         "ܐܪܡܝܐ",
17225         "arc"
17226     ],
17227     [
17228         "Egyptian Arabic",
17229         "مصرى",
17230         "arz"
17231     ],
17232     [
17233         "Assamese",
17234         "অসমীয়া",
17235         "as"
17236     ],
17237     [
17238         "Asturian",
17239         "asturianu",
17240         "ast"
17241     ],
17242     [
17243         "Avaric",
17244         "авар",
17245         "av"
17246     ],
17247     [
17248         "Aymara",
17249         "Aymar aru",
17250         "ay"
17251     ],
17252     [
17253         "Azerbaijani",
17254         "azərbaycanca",
17255         "az"
17256     ],
17257     [
17258         "تۆرکجه",
17259         "تۆرکجه",
17260         "azb"
17261     ],
17262     [
17263         "Bashkir",
17264         "башҡортса",
17265         "ba"
17266     ],
17267     [
17268         "Bavarian",
17269         "Boarisch",
17270         "bar"
17271     ],
17272     [
17273         "Samogitian",
17274         "žemaitėška",
17275         "bat-smg"
17276     ],
17277     [
17278         "Bikol Central",
17279         "Bikol Central",
17280         "bcl"
17281     ],
17282     [
17283         "Belarusian",
17284         "беларуская",
17285         "be"
17286     ],
17287     [
17288         "беларуская (тарашкевіца)‎",
17289         "беларуская (тарашкевіца)‎",
17290         "be-x-old"
17291     ],
17292     [
17293         "Bulgarian",
17294         "български",
17295         "bg"
17296     ],
17297     [
17298         "भोजपुरी",
17299         "भोजपुरी",
17300         "bh"
17301     ],
17302     [
17303         "Bislama",
17304         "Bislama",
17305         "bi"
17306     ],
17307     [
17308         "Banjar",
17309         "Bahasa Banjar",
17310         "bjn"
17311     ],
17312     [
17313         "Bambara",
17314         "bamanankan",
17315         "bm"
17316     ],
17317     [
17318         "Bangla",
17319         "বাংলা",
17320         "bn"
17321     ],
17322     [
17323         "Tibetan",
17324         "བོད་ཡིག",
17325         "bo"
17326     ],
17327     [
17328         "Bishnupriya",
17329         "বিষ্ণুপ্রিয়া মণিপুরী",
17330         "bpy"
17331     ],
17332     [
17333         "Breton",
17334         "brezhoneg",
17335         "br"
17336     ],
17337     [
17338         "Bosnian",
17339         "bosanski",
17340         "bs"
17341     ],
17342     [
17343         "Buginese",
17344         "ᨅᨔ ᨕᨘᨁᨗ",
17345         "bug"
17346     ],
17347     [
17348         "буряад",
17349         "буряад",
17350         "bxr"
17351     ],
17352     [
17353         "Catalan",
17354         "català",
17355         "ca"
17356     ],
17357     [
17358         "Chavacano de Zamboanga",
17359         "Chavacano de Zamboanga",
17360         "cbk-zam"
17361     ],
17362     [
17363         "Min Dong Chinese",
17364         "Mìng-dĕ̤ng-ngṳ̄",
17365         "cdo"
17366     ],
17367     [
17368         "Chechen",
17369         "нохчийн",
17370         "ce"
17371     ],
17372     [
17373         "Cebuano",
17374         "Cebuano",
17375         "ceb"
17376     ],
17377     [
17378         "Chamorro",
17379         "Chamoru",
17380         "ch"
17381     ],
17382     [
17383         "Cherokee",
17384         "ᏣᎳᎩ",
17385         "chr"
17386     ],
17387     [
17388         "Cheyenne",
17389         "Tsetsêhestâhese",
17390         "chy"
17391     ],
17392     [
17393         "Central Kurdish",
17394         "کوردیی ناوەندی",
17395         "ckb"
17396     ],
17397     [
17398         "Corsican",
17399         "corsu",
17400         "co"
17401     ],
17402     [
17403         "Cree",
17404         "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
17405         "cr"
17406     ],
17407     [
17408         "Crimean Turkish",
17409         "qırımtatarca",
17410         "crh"
17411     ],
17412     [
17413         "Czech",
17414         "čeština",
17415         "cs"
17416     ],
17417     [
17418         "Kashubian",
17419         "kaszëbsczi",
17420         "csb"
17421     ],
17422     [
17423         "Church Slavic",
17424         "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
17425         "cu"
17426     ],
17427     [
17428         "Chuvash",
17429         "Чӑвашла",
17430         "cv"
17431     ],
17432     [
17433         "Welsh",
17434         "Cymraeg",
17435         "cy"
17436     ],
17437     [
17438         "Danish",
17439         "dansk",
17440         "da"
17441     ],
17442     [
17443         "German",
17444         "Deutsch",
17445         "de"
17446     ],
17447     [
17448         "Zazaki",
17449         "Zazaki",
17450         "diq"
17451     ],
17452     [
17453         "Lower Sorbian",
17454         "dolnoserbski",
17455         "dsb"
17456     ],
17457     [
17458         "Divehi",
17459         "ދިވެހިބަސް",
17460         "dv"
17461     ],
17462     [
17463         "Dzongkha",
17464         "ཇོང་ཁ",
17465         "dz"
17466     ],
17467     [
17468         "Ewe",
17469         "eʋegbe",
17470         "ee"
17471     ],
17472     [
17473         "Greek",
17474         "Ελληνικά",
17475         "el"
17476     ],
17477     [
17478         "Emiliano-Romagnolo",
17479         "emiliàn e rumagnòl",
17480         "eml"
17481     ],
17482     [
17483         "English",
17484         "English",
17485         "en"
17486     ],
17487     [
17488         "Esperanto",
17489         "Esperanto",
17490         "eo"
17491     ],
17492     [
17493         "Spanish",
17494         "español",
17495         "es"
17496     ],
17497     [
17498         "Estonian",
17499         "eesti",
17500         "et"
17501     ],
17502     [
17503         "Basque",
17504         "euskara",
17505         "eu"
17506     ],
17507     [
17508         "Extremaduran",
17509         "estremeñu",
17510         "ext"
17511     ],
17512     [
17513         "Persian",
17514         "فارسی",
17515         "fa"
17516     ],
17517     [
17518         "Fulah",
17519         "Fulfulde",
17520         "ff"
17521     ],
17522     [
17523         "Finnish",
17524         "suomi",
17525         "fi"
17526     ],
17527     [
17528         "Võro",
17529         "Võro",
17530         "fiu-vro"
17531     ],
17532     [
17533         "Fijian",
17534         "Na Vosa Vakaviti",
17535         "fj"
17536     ],
17537     [
17538         "Faroese",
17539         "føroyskt",
17540         "fo"
17541     ],
17542     [
17543         "French",
17544         "français",
17545         "fr"
17546     ],
17547     [
17548         "Arpitan",
17549         "arpetan",
17550         "frp"
17551     ],
17552     [
17553         "Northern Frisian",
17554         "Nordfriisk",
17555         "frr"
17556     ],
17557     [
17558         "Friulian",
17559         "furlan",
17560         "fur"
17561     ],
17562     [
17563         "Western Frisian",
17564         "Frysk",
17565         "fy"
17566     ],
17567     [
17568         "Irish",
17569         "Gaeilge",
17570         "ga"
17571     ],
17572     [
17573         "Gagauz",
17574         "Gagauz",
17575         "gag"
17576     ],
17577     [
17578         "Gan Chinese",
17579         "贛語",
17580         "gan"
17581     ],
17582     [
17583         "Scottish Gaelic",
17584         "Gàidhlig",
17585         "gd"
17586     ],
17587     [
17588         "Galician",
17589         "galego",
17590         "gl"
17591     ],
17592     [
17593         "Gilaki",
17594         "گیلکی",
17595         "glk"
17596     ],
17597     [
17598         "Guarani",
17599         "Avañe'ẽ",
17600         "gn"
17601     ],
17602     [
17603         "Goan Konkani",
17604         "गोंयची कोंकणी / Gõychi Konknni",
17605         "gom"
17606     ],
17607     [
17608         "Gothic",
17609         "𐌲𐌿𐍄𐌹𐍃𐌺",
17610         "got"
17611     ],
17612     [
17613         "Gujarati",
17614         "ગુજરાતી",
17615         "gu"
17616     ],
17617     [
17618         "Manx",
17619         "Gaelg",
17620         "gv"
17621     ],
17622     [
17623         "Hausa",
17624         "Hausa",
17625         "ha"
17626     ],
17627     [
17628         "Hakka Chinese",
17629         "客家語/Hak-kâ-ngî",
17630         "hak"
17631     ],
17632     [
17633         "Hawaiian",
17634         "Hawaiʻi",
17635         "haw"
17636     ],
17637     [
17638         "Hebrew",
17639         "עברית",
17640         "he"
17641     ],
17642     [
17643         "Hindi",
17644         "हिन्दी",
17645         "hi"
17646     ],
17647     [
17648         "Fiji Hindi",
17649         "Fiji Hindi",
17650         "hif"
17651     ],
17652     [
17653         "Croatian",
17654         "hrvatski",
17655         "hr"
17656     ],
17657     [
17658         "Upper Sorbian",
17659         "hornjoserbsce",
17660         "hsb"
17661     ],
17662     [
17663         "Haitian Creole",
17664         "Kreyòl ayisyen",
17665         "ht"
17666     ],
17667     [
17668         "Hungarian",
17669         "magyar",
17670         "hu"
17671     ],
17672     [
17673         "Armenian",
17674         "Հայերեն",
17675         "hy"
17676     ],
17677     [
17678         "Interlingua",
17679         "interlingua",
17680         "ia"
17681     ],
17682     [
17683         "Indonesian",
17684         "Bahasa Indonesia",
17685         "id"
17686     ],
17687     [
17688         "Interlingue",
17689         "Interlingue",
17690         "ie"
17691     ],
17692     [
17693         "Igbo",
17694         "Igbo",
17695         "ig"
17696     ],
17697     [
17698         "Inupiaq",
17699         "Iñupiak",
17700         "ik"
17701     ],
17702     [
17703         "Iloko",
17704         "Ilokano",
17705         "ilo"
17706     ],
17707     [
17708         "Ido",
17709         "Ido",
17710         "io"
17711     ],
17712     [
17713         "Icelandic",
17714         "íslenska",
17715         "is"
17716     ],
17717     [
17718         "Italian",
17719         "italiano",
17720         "it"
17721     ],
17722     [
17723         "Inuktitut",
17724         "ᐃᓄᒃᑎᑐᑦ/inuktitut",
17725         "iu"
17726     ],
17727     [
17728         "Japanese",
17729         "日本語",
17730         "ja"
17731     ],
17732     [
17733         "Jamaican Creole English",
17734         "Patois",
17735         "jam"
17736     ],
17737     [
17738         "Lojban",
17739         "la .lojban.",
17740         "jbo"
17741     ],
17742     [
17743         "Javanese",
17744         "Basa Jawa",
17745         "jv"
17746     ],
17747     [
17748         "Georgian",
17749         "ქართული",
17750         "ka"
17751     ],
17752     [
17753         "Kara-Kalpak",
17754         "Qaraqalpaqsha",
17755         "kaa"
17756     ],
17757     [
17758         "Kabyle",
17759         "Taqbaylit",
17760         "kab"
17761     ],
17762     [
17763         "Kabardian",
17764         "Адыгэбзэ",
17765         "kbd"
17766     ],
17767     [
17768         "Kongo",
17769         "Kongo",
17770         "kg"
17771     ],
17772     [
17773         "Kikuyu",
17774         "Gĩkũyũ",
17775         "ki"
17776     ],
17777     [
17778         "Kazakh",
17779         "қазақша",
17780         "kk"
17781     ],
17782     [
17783         "Kalaallisut",
17784         "kalaallisut",
17785         "kl"
17786     ],
17787     [
17788         "Khmer",
17789         "ភាសាខ្មែរ",
17790         "km"
17791     ],
17792     [
17793         "Kannada",
17794         "ಕನ್ನಡ",
17795         "kn"
17796     ],
17797     [
17798         "Korean",
17799         "한국어",
17800         "ko"
17801     ],
17802     [
17803         "Komi-Permyak",
17804         "Перем Коми",
17805         "koi"
17806     ],
17807     [
17808         "Karachay-Balkar",
17809         "къарачай-малкъар",
17810         "krc"
17811     ],
17812     [
17813         "Kashmiri",
17814         "कॉशुर / کٲشُر",
17815         "ks"
17816     ],
17817     [
17818         "Colognian",
17819         "Ripoarisch",
17820         "ksh"
17821     ],
17822     [
17823         "Kurdish",
17824         "Kurdî",
17825         "ku"
17826     ],
17827     [
17828         "Komi",
17829         "коми",
17830         "kv"
17831     ],
17832     [
17833         "Cornish",
17834         "kernowek",
17835         "kw"
17836     ],
17837     [
17838         "Kyrgyz",
17839         "Кыргызча",
17840         "ky"
17841     ],
17842     [
17843         "Latin",
17844         "Latina",
17845         "la"
17846     ],
17847     [
17848         "Ladino",
17849         "Ladino",
17850         "lad"
17851     ],
17852     [
17853         "Luxembourgish",
17854         "Lëtzebuergesch",
17855         "lb"
17856     ],
17857     [
17858         "лакку",
17859         "лакку",
17860         "lbe"
17861     ],
17862     [
17863         "Lezghian",
17864         "лезги",
17865         "lez"
17866     ],
17867     [
17868         "Ganda",
17869         "Luganda",
17870         "lg"
17871     ],
17872     [
17873         "Limburgish",
17874         "Limburgs",
17875         "li"
17876     ],
17877     [
17878         "Ligurian",
17879         "Ligure",
17880         "lij"
17881     ],
17882     [
17883         "Lombard",
17884         "lumbaart",
17885         "lmo"
17886     ],
17887     [
17888         "Lingala",
17889         "lingála",
17890         "ln"
17891     ],
17892     [
17893         "Lao",
17894         "ລາວ",
17895         "lo"
17896     ],
17897     [
17898         "Northern Luri",
17899         "لۊری شومالی",
17900         "lrc"
17901     ],
17902     [
17903         "Lithuanian",
17904         "lietuvių",
17905         "lt"
17906     ],
17907     [
17908         "Latgalian",
17909         "latgaļu",
17910         "ltg"
17911     ],
17912     [
17913         "Latvian",
17914         "latviešu",
17915         "lv"
17916     ],
17917     [
17918         "Maithili",
17919         "मैथिली",
17920         "mai"
17921     ],
17922     [
17923         "Basa Banyumasan",
17924         "Basa Banyumasan",
17925         "map-bms"
17926     ],
17927     [
17928         "Moksha",
17929         "мокшень",
17930         "mdf"
17931     ],
17932     [
17933         "Malagasy",
17934         "Malagasy",
17935         "mg"
17936     ],
17937     [
17938         "Eastern Mari",
17939         "олык марий",
17940         "mhr"
17941     ],
17942     [
17943         "Maori",
17944         "Māori",
17945         "mi"
17946     ],
17947     [
17948         "Minangkabau",
17949         "Baso Minangkabau",
17950         "min"
17951     ],
17952     [
17953         "Macedonian",
17954         "македонски",
17955         "mk"
17956     ],
17957     [
17958         "Malayalam",
17959         "മലയാളം",
17960         "ml"
17961     ],
17962     [
17963         "Mongolian",
17964         "монгол",
17965         "mn"
17966     ],
17967     [
17968         "Marathi",
17969         "मराठी",
17970         "mr"
17971     ],
17972     [
17973         "Western Mari",
17974         "кырык мары",
17975         "mrj"
17976     ],
17977     [
17978         "Malay",
17979         "Bahasa Melayu",
17980         "ms"
17981     ],
17982     [
17983         "Maltese",
17984         "Malti",
17985         "mt"
17986     ],
17987     [
17988         "Mirandese",
17989         "Mirandés",
17990         "mwl"
17991     ],
17992     [
17993         "Burmese",
17994         "မြန်မာဘာသာ",
17995         "my"
17996     ],
17997     [
17998         "Erzya",
17999         "эрзянь",
18000         "myv"
18001     ],
18002     [
18003         "Mazanderani",
18004         "مازِرونی",
18005         "mzn"
18006     ],
18007     [
18008         "Nauru",
18009         "Dorerin Naoero",
18010         "na"
18011     ],
18012     [
18013         "Nāhuatl",
18014         "Nāhuatl",
18015         "nah"
18016     ],
18017     [
18018         "Neapolitan",
18019         "Napulitano",
18020         "nap"
18021     ],
18022     [
18023         "Low German",
18024         "Plattdüütsch",
18025         "nds"
18026     ],
18027     [
18028         "Low Saxon",
18029         "Nedersaksies",
18030         "nds-nl"
18031     ],
18032     [
18033         "Nepali",
18034         "नेपाली",
18035         "ne"
18036     ],
18037     [
18038         "Newari",
18039         "नेपाल भाषा",
18040         "new"
18041     ],
18042     [
18043         "Dutch",
18044         "Nederlands",
18045         "nl"
18046     ],
18047     [
18048         "Norwegian Nynorsk",
18049         "norsk nynorsk",
18050         "nn"
18051     ],
18052     [
18053         "Norwegian",
18054         "norsk bokmål",
18055         "no"
18056     ],
18057     [
18058         "Novial",
18059         "Novial",
18060         "nov"
18061     ],
18062     [
18063         "Nouormand",
18064         "Nouormand",
18065         "nrm"
18066     ],
18067     [
18068         "Northern Sotho",
18069         "Sesotho sa Leboa",
18070         "nso"
18071     ],
18072     [
18073         "Navajo",
18074         "Diné bizaad",
18075         "nv"
18076     ],
18077     [
18078         "Nyanja",
18079         "Chi-Chewa",
18080         "ny"
18081     ],
18082     [
18083         "Occitan",
18084         "occitan",
18085         "oc"
18086     ],
18087     [
18088         "Livvi-Karelian",
18089         "Livvinkarjala",
18090         "olo"
18091     ],
18092     [
18093         "Oromo",
18094         "Oromoo",
18095         "om"
18096     ],
18097     [
18098         "Odia",
18099         "ଓଡ଼ିଆ",
18100         "or"
18101     ],
18102     [
18103         "Ossetic",
18104         "Ирон",
18105         "os"
18106     ],
18107     [
18108         "Punjabi",
18109         "ਪੰਜਾਬੀ",
18110         "pa"
18111     ],
18112     [
18113         "Pangasinan",
18114         "Pangasinan",
18115         "pag"
18116     ],
18117     [
18118         "Pampanga",
18119         "Kapampangan",
18120         "pam"
18121     ],
18122     [
18123         "Papiamento",
18124         "Papiamentu",
18125         "pap"
18126     ],
18127     [
18128         "Picard",
18129         "Picard",
18130         "pcd"
18131     ],
18132     [
18133         "Pennsylvania German",
18134         "Deitsch",
18135         "pdc"
18136     ],
18137     [
18138         "Palatine German",
18139         "Pälzisch",
18140         "pfl"
18141     ],
18142     [
18143         "Pali",
18144         "पालि",
18145         "pi"
18146     ],
18147     [
18148         "Norfuk / Pitkern",
18149         "Norfuk / Pitkern",
18150         "pih"
18151     ],
18152     [
18153         "Polish",
18154         "polski",
18155         "pl"
18156     ],
18157     [
18158         "Piedmontese",
18159         "Piemontèis",
18160         "pms"
18161     ],
18162     [
18163         "Western Punjabi",
18164         "پنجابی",
18165         "pnb"
18166     ],
18167     [
18168         "Pontic",
18169         "Ποντιακά",
18170         "pnt"
18171     ],
18172     [
18173         "Pashto",
18174         "پښتو",
18175         "ps"
18176     ],
18177     [
18178         "Portuguese",
18179         "português",
18180         "pt"
18181     ],
18182     [
18183         "Quechua",
18184         "Runa Simi",
18185         "qu"
18186     ],
18187     [
18188         "Romansh",
18189         "rumantsch",
18190         "rm"
18191     ],
18192     [
18193         "Romani",
18194         "Romani",
18195         "rmy"
18196     ],
18197     [
18198         "Rundi",
18199         "Kirundi",
18200         "rn"
18201     ],
18202     [
18203         "Romanian",
18204         "română",
18205         "ro"
18206     ],
18207     [
18208         "Aromanian",
18209         "armãneashti",
18210         "roa-rup"
18211     ],
18212     [
18213         "tarandíne",
18214         "tarandíne",
18215         "roa-tara"
18216     ],
18217     [
18218         "Russian",
18219         "русский",
18220         "ru"
18221     ],
18222     [
18223         "Rusyn",
18224         "русиньскый",
18225         "rue"
18226     ],
18227     [
18228         "Kinyarwanda",
18229         "Kinyarwanda",
18230         "rw"
18231     ],
18232     [
18233         "Sanskrit",
18234         "संस्कृतम्",
18235         "sa"
18236     ],
18237     [
18238         "Sakha",
18239         "саха тыла",
18240         "sah"
18241     ],
18242     [
18243         "Sardinian",
18244         "sardu",
18245         "sc"
18246     ],
18247     [
18248         "Sicilian",
18249         "sicilianu",
18250         "scn"
18251     ],
18252     [
18253         "Scots",
18254         "Scots",
18255         "sco"
18256     ],
18257     [
18258         "Sindhi",
18259         "سنڌي",
18260         "sd"
18261     ],
18262     [
18263         "Northern Sami",
18264         "sámegiella",
18265         "se"
18266     ],
18267     [
18268         "Sango",
18269         "Sängö",
18270         "sg"
18271     ],
18272     [
18273         "Serbo-Croatian",
18274         "srpskohrvatski / српскохрватски",
18275         "sh"
18276     ],
18277     [
18278         "Sinhala",
18279         "සිංහල",
18280         "si"
18281     ],
18282     [
18283         "Simple English",
18284         "Simple English",
18285         "simple"
18286     ],
18287     [
18288         "Slovak",
18289         "slovenčina",
18290         "sk"
18291     ],
18292     [
18293         "Slovenian",
18294         "slovenščina",
18295         "sl"
18296     ],
18297     [
18298         "Samoan",
18299         "Gagana Samoa",
18300         "sm"
18301     ],
18302     [
18303         "Shona",
18304         "chiShona",
18305         "sn"
18306     ],
18307     [
18308         "Somali",
18309         "Soomaaliga",
18310         "so"
18311     ],
18312     [
18313         "Albanian",
18314         "shqip",
18315         "sq"
18316     ],
18317     [
18318         "Serbian",
18319         "српски / srpski",
18320         "sr"
18321     ],
18322     [
18323         "Sranan Tongo",
18324         "Sranantongo",
18325         "srn"
18326     ],
18327     [
18328         "Swati",
18329         "SiSwati",
18330         "ss"
18331     ],
18332     [
18333         "Southern Sotho",
18334         "Sesotho",
18335         "st"
18336     ],
18337     [
18338         "Saterland Frisian",
18339         "Seeltersk",
18340         "stq"
18341     ],
18342     [
18343         "Sundanese",
18344         "Basa Sunda",
18345         "su"
18346     ],
18347     [
18348         "Swedish",
18349         "svenska",
18350         "sv"
18351     ],
18352     [
18353         "Swahili",
18354         "Kiswahili",
18355         "sw"
18356     ],
18357     [
18358         "Silesian",
18359         "ślůnski",
18360         "szl"
18361     ],
18362     [
18363         "Tamil",
18364         "தமிழ்",
18365         "ta"
18366     ],
18367     [
18368         "Tulu",
18369         "ತುಳು",
18370         "tcy"
18371     ],
18372     [
18373         "Telugu",
18374         "తెలుగు",
18375         "te"
18376     ],
18377     [
18378         "Tetum",
18379         "tetun",
18380         "tet"
18381     ],
18382     [
18383         "Tajik",
18384         "тоҷикӣ",
18385         "tg"
18386     ],
18387     [
18388         "Thai",
18389         "ไทย",
18390         "th"
18391     ],
18392     [
18393         "Tigrinya",
18394         "ትግርኛ",
18395         "ti"
18396     ],
18397     [
18398         "Turkmen",
18399         "Türkmençe",
18400         "tk"
18401     ],
18402     [
18403         "Tagalog",
18404         "Tagalog",
18405         "tl"
18406     ],
18407     [
18408         "Tswana",
18409         "Setswana",
18410         "tn"
18411     ],
18412     [
18413         "Tongan",
18414         "lea faka-Tonga",
18415         "to"
18416     ],
18417     [
18418         "Tok Pisin",
18419         "Tok Pisin",
18420         "tpi"
18421     ],
18422     [
18423         "Turkish",
18424         "Türkçe",
18425         "tr"
18426     ],
18427     [
18428         "Tsonga",
18429         "Xitsonga",
18430         "ts"
18431     ],
18432     [
18433         "Tatar",
18434         "татарча/tatarça",
18435         "tt"
18436     ],
18437     [
18438         "Tumbuka",
18439         "chiTumbuka",
18440         "tum"
18441     ],
18442     [
18443         "Twi",
18444         "Twi",
18445         "tw"
18446     ],
18447     [
18448         "Tahitian",
18449         "reo tahiti",
18450         "ty"
18451     ],
18452     [
18453         "Tuvinian",
18454         "тыва дыл",
18455         "tyv"
18456     ],
18457     [
18458         "Udmurt",
18459         "удмурт",
18460         "udm"
18461     ],
18462     [
18463         "Uyghur",
18464         "ئۇيغۇرچە / Uyghurche",
18465         "ug"
18466     ],
18467     [
18468         "Ukrainian",
18469         "українська",
18470         "uk"
18471     ],
18472     [
18473         "Urdu",
18474         "اردو",
18475         "ur"
18476     ],
18477     [
18478         "Uzbek",
18479         "oʻzbekcha/ўзбекча",
18480         "uz"
18481     ],
18482     [
18483         "Venda",
18484         "Tshivenda",
18485         "ve"
18486     ],
18487     [
18488         "Venetian",
18489         "vèneto",
18490         "vec"
18491     ],
18492     [
18493         "Veps",
18494         "vepsän kel’",
18495         "vep"
18496     ],
18497     [
18498         "Vietnamese",
18499         "Tiếng Việt",
18500         "vi"
18501     ],
18502     [
18503         "West Flemish",
18504         "West-Vlams",
18505         "vls"
18506     ],
18507     [
18508         "Volapük",
18509         "Volapük",
18510         "vo"
18511     ],
18512     [
18513         "Walloon",
18514         "walon",
18515         "wa"
18516     ],
18517     [
18518         "Waray",
18519         "Winaray",
18520         "war"
18521     ],
18522     [
18523         "Wolof",
18524         "Wolof",
18525         "wo"
18526     ],
18527     [
18528         "Wu Chinese",
18529         "吴语",
18530         "wuu"
18531     ],
18532     [
18533         "Kalmyk",
18534         "хальмг",
18535         "xal"
18536     ],
18537     [
18538         "Xhosa",
18539         "isiXhosa",
18540         "xh"
18541     ],
18542     [
18543         "Mingrelian",
18544         "მარგალური",
18545         "xmf"
18546     ],
18547     [
18548         "Yiddish",
18549         "ייִדיש",
18550         "yi"
18551     ],
18552     [
18553         "Yoruba",
18554         "Yorùbá",
18555         "yo"
18556     ],
18557     [
18558         "Zhuang",
18559         "Vahcuengh",
18560         "za"
18561     ],
18562     [
18563         "Zeelandic",
18564         "Zeêuws",
18565         "zea"
18566     ],
18567     [
18568         "Chinese",
18569         "中文",
18570         "zh"
18571     ],
18572     [
18573         "Classical Chinese",
18574         "文言",
18575         "zh-classical"
18576     ],
18577     [
18578         "Chinese (Min Nan)",
18579         "Bân-lâm-gú",
18580         "zh-min-nan"
18581     ],
18582     [
18583         "Cantonese",
18584         "粵語",
18585         "zh-yue"
18586     ],
18587     [
18588         "Zulu",
18589         "isiZulu",
18590         "zu"
18591     ]
18592 ];
18593
18594 var amenity = {"arts_centre":{"Świetlica wiejska":{"count":62},"Дом культуры":{"count":182}},"bank":{"ABANCA":{"count":83},"ABN AMRO":{"count":152},"ABSA":{"count":105},"AIB":{"count":85},"ANZ":{"count":378},"ASB Bank":{"count":51},"ATB Financial":{"count":68},"AXA":{"count":106},"Agribank":{"count":58},"Akbank":{"count":129},"Alior Bank":{"count":180},"Allahabad Bank":{"count":52},"Allied Bank":{"count":67},"Alpha Bank":{"count":329},"Andhra Bank":{"count":97},"Antonveneta":{"count":56},"Argenta":{"count":125},"Asia United Bank":{"count":57},"Askari Bank":{"count":71},"Associated Bank":{"count":55},"Axis Bank":{"count":198},"BAC":{"count":77},"BAWAG PSK":{"count":97},"BB&T":{"count":418},"BBBank":{"count":58},"BBK":{"count":122},"BBVA":{"count":1445},"BBVA Bancomer":{"count":157},"BBVA Compass":{"count":80},"BBVA Continental":{"count":74},"BBVA Francés":{"count":158},"BCA":{"count":135},"BCI":{"count":140},"BCP":{"count":226},"BCR":{"count":232},"BDO":{"count":538},"BGŻ BNP Paribas":{"count":74},"BMCE":{"count":53},"BMN":{"count":88},"BMO":{"count":339},"BMO Harris Bank":{"count":72},"BNA":{"count":70},"BNI":{"count":136},"BNL":{"count":159},"BNP Paribas":{"count":1165},"BNP Paribas Fortis":{"count":303},"BOC":{"count":95},"BPH":{"count":63},"BPI":{"count":579},"BPI Family Savings Bank":{"count":54},"BRD":{"count":276},"BRED":{"count":70},"BRI":{"count":209},"BW-Bank":{"count":95},"BZ WBK":{"count":156},"Banamex":{"count":356},"Banc Sabadell":{"count":175},"Banca Intesa":{"count":92},"Banca March":{"count":51},"Banca Popolare di Milano":{"count":99},"Banca Popolare di Novara":{"count":79},"Banca Popolare di Sondrio":{"count":105},"Banca Popolare di Verona":{"count":59},"Banca Popolare di Vicenza":{"count":119},"Banca Românească":{"count":61},"Banca Sella":{"count":56},"Banca Transilvania":{"count":167},"Banco Agrario":{"count":58},"Banco Azteca":{"count":119},"Banco BCI":{"count":74},"Banco Bradesco":{"count":226},"Banco Continental":{"count":64},"Banco Estado":{"count":153},"Banco Fassil":{"count":59},"Banco G&T Continental":{"count":84},"Banco General":{"count":53},"Banco Industrial":{"count":91},"Banco Internacional":{"count":62},"Banco Itaú":{"count":351},"Banco Nacional":{"count":143},"Banco Nación":{"count":149},"Banco Pastor":{"count":74},"Banco Pichincha":{"count":109},"Banco Popular":{"count":619},"Banco Provincia":{"count":138},"Banco Sabadell":{"count":189},"Banco Santander":{"count":112},"Banco Sol":{"count":74},"Banco de Bogotá":{"count":74},"Banco de Chile":{"count":175},"Banco de Costa Rica":{"count":123},"Banco de Desarrollo Banrural":{"count":85},"Banco de Occidente":{"count":67},"Banco de Venezuela":{"count":76},"Banco de la Nación":{"count":156},"Banco de la Nación Argentina":{"count":166},"Banco di Napoli":{"count":79},"Banco di Sardegna":{"count":79},"Banco do Brasil":{"count":1313},"Banco do Nordeste":{"count":56},"BancoEstado":{"count":121},"Bancolombia":{"count":170},"Bancomer":{"count":227},"Bancpost":{"count":77},"Banesco":{"count":209},"Bangkok Bank":{"count":69},"Bank Al Habib":{"count":52},"Bank Alfalah":{"count":63},"Bank Austria":{"count":123},"Bank BCA":{"count":71},"Bank BNI":{"count":67},"Bank BPH":{"count":56},"Bank BRI":{"count":196},"Bank Danamon":{"count":60},"Bank Mandiri":{"count":232},"Bank Mega":{"count":54},"Bank Spółdzielczy":{"count":395},"Bank Zachodni WBK":{"count":103},"Bank of Africa":{"count":59},"Bank of America":{"count":1787},"Bank of Baroda":{"count":122},"Bank of Ceylon":{"count":74},"Bank of China":{"count":152},"Bank of Commerce":{"count":69},"Bank of India":{"count":113},"Bank of Ireland":{"count":151},"Bank of Montreal":{"count":157},"Bank of New Zealand":{"count":63},"Bank of Scotland":{"count":122},"Bank of the West":{"count":173},"Bankia":{"count":613},"Bankinter":{"count":139},"Banner Bank":{"count":53},"Banorte":{"count":260},"Banque Atlantique":{"count":57},"Banque Nationale":{"count":137},"Banque Populaire":{"count":919},"Banrisul":{"count":101},"Banrural":{"count":84},"Barclays":{"count":1243},"Bcc":{"count":54},"Belfius":{"count":285},"Bendigo Bank":{"count":140},"Berliner Volksbank":{"count":73},"Bicentenario":{"count":173},"Bradesco":{"count":751},"Budapest Bank":{"count":56},"CBAO":{"count":53},"CEC Bank":{"count":121},"CGD":{"count":52},"CIB Bank":{"count":64},"CIBC":{"count":574},"CIC":{"count":742},"CIMB Bank":{"count":64},"CNEP":{"count":52},"Caisse Desjardins":{"count":69},"Caisse d'Épargne":{"count":1607},"Caixa":{"count":239},"Caixa Econômica Federal":{"count":573},"Caixa Geral de Depósitos":{"count":231},"CaixaBank":{"count":343},"Caja Círculo":{"count":68},"Caja Duero":{"count":90},"Caja España":{"count":74},"Caja Rural":{"count":216},"Caja Rural de Jaén":{"count":55},"CajaSur":{"count":73},"Cajamar":{"count":216},"Cajero Automatico Bancared":{"count":123},"Canara Bank":{"count":270},"Capital One":{"count":199},"Carige":{"count":57},"Cariparma":{"count":69},"Cassa di Risparmio del Veneto":{"count":102},"CatalunyaCaixa":{"count":107},"Central Bank of India":{"count":60},"Chase":{"count":1658},"China Bank":{"count":156},"China Bank Savings":{"count":54},"China Construction Bank":{"count":68},"Citibank":{"count":485},"Citizens Bank":{"count":248},"Clydesdale Bank":{"count":55},"Columbia Bank":{"count":79},"Comerica Bank":{"count":67},"Commerce Bank":{"count":61},"Commercial Bank":{"count":75},"Commercial Bank of Ceylon PLC":{"count":100},"Commerzbank":{"count":879},"Commonwealth Bank":{"count":376},"Corporation Bank":{"count":92},"Credem":{"count":77},"Credicoop":{"count":111},"Credit Agricole":{"count":104},"Credit Suisse":{"count":93},"Crelan":{"count":53},"Crédit Agricole":{"count":2544},"Crédit Mutuel":{"count":1129},"Crédit Mutuel de Bretagne":{"count":368},"Crédit du Nord":{"count":148},"Crédito Agrícola":{"count":87},"Cбербанк":{"count":74},"Danske Bank":{"count":157},"Davivienda":{"count":172},"De Venezuela":{"count":87},"Denizbank":{"count":58},"Desjardins":{"count":80},"Deutsche Bank":{"count":995},"Dubai Islamic Bank":{"count":71},"EastWest Bank":{"count":127},"Ecobank":{"count":197},"Erste Bank":{"count":200},"Eurobank":{"count":261},"Express Union":{"count":58},"FNB":{"count":143},"Federal Bank":{"count":88},"Fifth Third Bank":{"count":234},"Finansbank":{"count":68},"First Bank":{"count":91},"First Citizens Bank":{"count":88},"First National Bank":{"count":209},"Galicia":{"count":179},"Garanti":{"count":58},"Garanti Bankası":{"count":82},"Getin Bank":{"count":112},"Groupama":{"count":61},"HDFC Bank":{"count":219},"HNB":{"count":67},"HSBC":{"count":1748},"Halifax":{"count":367},"Halkbank":{"count":74},"Hamburger Sparkasse":{"count":159},"Handelsbanken":{"count":250},"Hong Leong Bank":{"count":51},"Hrvatska poštanska banka":{"count":54},"Huntington Bank":{"count":110},"HypoVereinsbank":{"count":408},"ICBC":{"count":158},"ICICI Bank":{"count":224},"IDBI Bank":{"count":73},"ING":{"count":654},"ING Bank Śląski":{"count":128},"IberCaja":{"count":209},"Indian Bank":{"count":98},"Indian Overseas Bank":{"count":108},"Interbank":{"count":131},"Intesa San Paolo":{"count":257},"Itaú":{"count":726},"K&H Bank":{"count":75},"KBC":{"count":273},"Kasa Stefczyka":{"count":65},"Key Bank":{"count":382},"Komerční banka":{"count":180},"Kreissparkasse":{"count":600},"Kreissparkasse Köln":{"count":69},"Kutxabank":{"count":68},"LCL":{"count":903},"La Banque Postale":{"count":124},"La Caixa":{"count":1144},"Laboral Kutxa":{"count":66},"Landbank":{"count":115},"Liberbank":{"count":164},"Lloyds Bank":{"count":612},"M&T Bank":{"count":184},"MCB":{"count":62},"MCB Bank":{"count":54},"MONETA Money Bank":{"count":92},"Macro":{"count":174},"Maybank":{"count":234},"Meezan Bank":{"count":63},"Mercantil":{"count":132},"Metro Bank":{"count":57},"Metrobank":{"count":434},"Millennium BCP":{"count":119},"Millennium Bank":{"count":386},"Monte dei Paschi di Siena":{"count":265},"Montepio":{"count":113},"NAB":{"count":205},"NSB":{"count":51},"NatWest":{"count":800},"National Bank":{"count":147},"Nationwide":{"count":337},"Nedbank":{"count":100},"Nordea":{"count":331},"Novo Banco":{"count":101},"OLB":{"count":57},"OTP":{"count":362},"Oberbank":{"count":103},"Occidental de Descuento":{"count":68},"Oldenburgische Landesbank":{"count":68},"One Network Bank":{"count":91},"Osuuspankki":{"count":89},"PBZ":{"count":65},"PKO":{"count":58},"PKO BP":{"count":561},"PNB":{"count":323},"PNC":{"count":52},"PNC Bank":{"count":639},"PSBank":{"count":108},"Patagonia":{"count":94},"Pekao SA":{"count":155},"Peoples Bank":{"count":254},"Philippine National Bank":{"count":69},"Piraeus Bank":{"count":96},"Popular":{"count":104},"Postbank":{"count":567},"Postbank Finanzcenter":{"count":65},"Provincial":{"count":135},"Public Bank":{"count":90},"Punjab National Bank":{"count":134},"RBC":{"count":487},"RBC Financial Group":{"count":59},"RBS":{"count":190},"RCBC":{"count":144},"RCBC Savings Bank":{"count":84},"Rabobank":{"count":557},"Raiffeisen Polbank":{"count":78},"Raiffeisenbank":{"count":2705},"Regions Bank":{"count":204},"Republic Bank":{"count":85},"Royal Bank":{"count":90},"Royal Bank of Canada":{"count":56},"Royal Bank of Scotland":{"count":129},"SEB":{"count":129},"SNS Bank":{"count":58},"Sabadell":{"count":97},"Sampath Bank":{"count":87},"Santander":{"count":3268},"Santander Consumer Bank":{"count":109},"Santander Río":{"count":239},"Santander Totta":{"count":201},"Sberbank":{"count":135},"Scotiabank":{"count":1144},"Security Bank":{"count":171},"Sicredi":{"count":94},"Slovenská sporiteľňa":{"count":165},"Société Générale":{"count":1136},"Sparda-Bank":{"count":277},"Sparkasse":{"count":4667},"Sparkasse Aachen":{"count":56},"Sparkasse KölnBonn":{"count":76},"Stadtsparkasse":{"count":68},"Stanbic Bank":{"count":63},"Standard Bank":{"count":165},"Standard Chartered":{"count":95},"Standard Chartered Bank":{"count":74},"State Bank of India":{"count":1013},"SunTrust":{"count":322},"Supervielle":{"count":72},"Swedbank":{"count":252},"Syndicate Bank":{"count":118},"TCF Bank":{"count":85},"TD Bank":{"count":425},"TD Canada Trust":{"count":675},"TEB":{"count":56},"TSB":{"count":259},"Takarékszövetkezet":{"count":120},"Targobank":{"count":279},"Tatra banka":{"count":70},"Türkiye İş Bankası":{"count":53},"UBS":{"count":169},"UCO Bank":{"count":51},"UCPB":{"count":122},"UOB":{"count":126},"US Bank":{"count":723},"Ulster Bank":{"count":100},"Umpqua Bank":{"count":103},"UniCredit Bank":{"count":548},"Unicaja Banco":{"count":182},"Unicredit Banca":{"count":496},"Union Bank":{"count":304},"United Bank":{"count":68},"VR-Bank":{"count":506},"Vakıfbank":{"count":85},"Veneto Banca":{"count":73},"Vijaya Bank":{"count":56},"Volks- und Raiffeisenbank":{"count":53},"Volksbank":{"count":2665},"Volksbank Mittelhessen":{"count":53},"Volksbank Raiffeisenbank":{"count":63},"VÚB":{"count":105},"Washington Federal":{"count":65},"Wells Fargo":{"count":1947},"Western Union":{"count":440},"Westpac":{"count":322},"Yorkshire Bank":{"count":95},"Yorkshire Building Society":{"count":69},"Zagrebačka banka":{"count":54},"Ziraat Bankası":{"count":172},"mBank":{"count":70},"ČSOB":{"count":211},"Česká spořitelna":{"count":243},"İş Bankası":{"count":112},"Εθνική Τράπεζα":{"count":103},"Πειραιώς":{"count":120},"Τράπεζα Πειραιώς":{"count":104},"Авангард":{"count":76},"Альфа-Банк":{"count":301},"Банк Москвы":{"count":176},"Банка ДСК":{"count":63},"Белагропромбанк":{"count":184},"Беларусбанк":{"count":570},"Белинвестбанк":{"count":78},"Бинбанк":{"count":114},"ВТБ":{"count":80},"ВТБ24":{"count":545},"Возрождение":{"count":81},"Газпромбанк":{"count":161},"Генбанк":{"count":83},"Казкоммерцбанк":{"count":74},"МДМ Банк":{"count":52},"Московский индустриальный банк":{"count":53},"Мособлбанк":{"count":54},"Народный банк":{"count":63},"ОТП Банк":{"count":54},"Открытие":{"count":92},"Ощадбанк":{"count":883},"ПУМБ":{"count":78},"Почта Банк":{"count":65},"ПриватБанк":{"count":1018},"Приватбанк":{"count":76},"Приднестровский Сбербанк":{"count":59},"Приорбанк":{"count":69},"Промсвязьбанк":{"count":133},"РНКБ":{"count":124},"Райффайзен":{"count":65},"Райффайзен Банк Аваль":{"count":125},"Райффайзенбанк":{"count":52},"Росбанк":{"count":218},"Россельхозбанк":{"count":374},"Русский стандарт":{"count":55},"Сбербанк":{"count":6921},"Совкомбанк":{"count":186},"УкрСиббанк":{"count":213},"Укрсоцбанк":{"count":57},"Уралсиб":{"count":130},"Хоум Кредит":{"count":53},"בנק הפועלים":{"count":112},"בנק לאומי":{"count":83},"بانک":{"count":219},"بانک آینده":{"count":58},"بانک اقتصاد نوین":{"count":78},"بانک انصار":{"count":99},"بانک تجارت":{"count":365},"بانک رفاه":{"count":138},"بانک رفاه کارگران":{"count":72},"بانک سپه":{"count":348},"بانک شهر":{"count":93},"بانک صادرات":{"count":492},"بانک قوامین":{"count":110},"بانک مسکن":{"count":263},"بانک ملت":{"count":428},"بانک ملی":{"count":561},"بانک ملی ایران":{"count":80},"بانک مهر اقتصاد":{"count":92},"بانک پارسیان":{"count":103},"بانک پاسارگاد":{"count":107},"بانک کشاورزی":{"count":277},"صادرات":{"count":85},"ملی":{"count":67},"پست بانک":{"count":71},"ธนาคารกรุงเทพ":{"count":121},"ธนาคารกรุงไทย":{"count":85},"ธนาคารกสิกรไทย":{"count":108},"ธนาคารออมสิน":{"count":71},"ธนาคารไทยพาณิชย์":{"count":95},"みずほ銀行":{"count":255},"りそな銀行":{"count":135},"三井住友銀行":{"count":204},"三菱東京UFJ銀行":{"count":235},"中国农业银行":{"count":198},"中国工商银行":{"count":181},"中国建设银行":{"count":158},"中国邮政储蓄银行":{"count":76},"中国银行":{"count":275},"交通银行":{"count":68},"京都中央信用金庫":{"count":53},"京都銀行":{"count":66},"农业银行":{"count":78},"北海道銀行":{"count":51},"合作金庫銀行":{"count":55},"土地銀行":{"count":54},"工商银行":{"count":160},"建设银行":{"count":89},"彰化銀行":{"count":53},"招商银行":{"count":94},"横浜銀行":{"count":92},"第一銀行":{"count":78},"華南銀行":{"count":52},"국민은행":{"count":199,"tags":{"name:en":"Gungmin Bank"}},"기업은행":{"count":53},"농협":{"count":148},"새마을금고":{"count":102},"신한은행":{"count":245,"tags":{"name:en":"Sinhan Bank"}},"우리은행":{"count":316,"tags":{"name:en":"Uri Bank"}},"하나은행":{"count":85}},"bar":{"Bar Centrale":{"count":141},"Bar Sport":{"count":90},"Beach Bar":{"count":80},"Pool Bar":{"count":54}},"bicycle_rental":{"Bicing":{"count":130},"Call a Bike":{"count":95},"Grid":{"count":51},"Mibici":{"count":116},"metropolradruhr":{"count":91}},"bureau_de_change":{"Abitab":{"count":55},"Change":{"count":51},"Travelex":{"count":75},"Western Union":{"count":189}},"cafe":{"85度C":{"count":128},"Bar Centrale":{"count":77},"Bar Kafe":{"count":253},"Barista":{"count":65},"Bistro":{"count":60},"Bonafide":{"count":63},"Cafe Coffee Day":{"count":239},"Cafe Nero":{"count":52},"Cafeteria":{"count":579},"Cafetería":{"count":61},"Caffè Nero":{"count":316},"Café Amazon":{"count":241},"Café Central":{"count":115},"Café de la Place":{"count":55},"Café des Sports":{"count":71},"Caribou Coffee":{"count":184},"Coffee Fellows":{"count":77},"Coffee House":{"count":71},"Coffee Island":{"count":51},"Coffee Shop":{"count":180},"Coffee Time":{"count":133},"Costa":{"count":1403},"Country Style":{"count":58},"Dolce Vita":{"count":55},"Dunkin' Donuts":{"count":1662,"tags":{"cuisine":"donut"}},"Eiscafe Dolomiti":{"count":51},"Eiscafe Venezia":{"count":237},"Espresso House":{"count":122},"Havanna":{"count":81},"Internet Cafe":{"count":95},"Jamba Juice":{"count":86},"Kafe":{"count":55},"Krispy Kreme":{"count":63},"Le Pain Quotidien":{"count":59},"McCafé":{"count":72,"tags":{"amenity":"cafe","cuisine":"coffee_shop"}},"Peet's Coffee & Tea":{"count":82},"Pret A Manger":{"count":174},"Prime":{"count":51},"Second Cup":{"count":234},"Segafredo":{"count":103},"Starbucks":{"count":8463,"tags":{"cuisine":"coffee_shop"}},"Subway":{"count":114},"Tchibo":{"count":168},"The Coffee Bean & Tea Leaf":{"count":93},"The Coffee Club":{"count":81},"Tim Hortons":{"count":1945},"Traveler's Coffee":{"count":70},"Venezia":{"count":55},"Wayne's Coffee":{"count":52},"Берёзка":{"count":52},"Бистро":{"count":84},"Буфет":{"count":56},"Встреча":{"count":83},"Даблби":{"count":59},"Закусочная":{"count":101},"Кофе Хауз":{"count":119},"Кофейня":{"count":78},"Лакомка":{"count":62},"Летнее кафе":{"count":61},"Оазис":{"count":54},"Пельменная":{"count":63},"Пиццерия":{"count":60},"Рандеву":{"count":54},"Сказка":{"count":66},"Смак":{"count":62},"Старбакс":{"count":55},"Столовая":{"count":1181},"Теремок":{"count":64},"Уют":{"count":115},"Хуторок":{"count":59},"Шашлычная":{"count":153},"Шоколад":{"count":54},"Шоколадница":{"count":252},"ארומה":{"count":64},"مقهى":{"count":136},"คาเฟ่ อเมซอน":{"count":59},"エクセルシオール カフェ":{"count":61},"カフェ・ド・クリエ":{"count":80,"tags":{"name:en":"Cafe de CRIE"}},"カフェ・ベローチェ":{"count":105},"コメダ珈琲店":{"count":179},"サンマルクカフェ":{"count":156},"スターバックス":{"count":558,"tags":{"name:en":"Starbucks"}},"タリーズコーヒー":{"count":243},"ドトールコーヒーショップ":{"count":489},"星巴克":{"count":146},"스타벅스":{"count":52}},"car_rental":{"Alamo":{"count":57},"Avis":{"count":604},"Budget":{"count":218},"Enterprise":{"count":594},"Enterprise Rent-a-Car":{"count":51},"Europcar":{"count":611},"Hertz":{"count":654},"Localiza":{"count":59},"Sixt":{"count":323},"Thrifty":{"count":81},"U-Haul":{"count":94},"オリックスレンタカー":{"count":54},"トヨタレンタカー":{"count":57},"トヨタレンタリース":{"count":63},"ニッポンレンタカー":{"count":113}},"car_wash":{"Aral":{"count":88},"Autolavaggio":{"count":52},"BP":{"count":63},"Esso":{"count":55},"H-E-B Car Wash":{"count":71},"Intermarché":{"count":60},"Lavage Auto":{"count":60},"Lavazh":{"count":52},"Myjnia":{"count":54},"Myjnia bezdotykowa":{"count":93},"Myjnia samochodowa":{"count":66},"Shell":{"count":162},"Spălătorie Auto":{"count":69},"Spălătorie auto":{"count":52},"Автомийка":{"count":63}},"cinema":{"Cinema City":{"count":61},"Cinemark":{"count":87},"Cinemex":{"count":70},"Cinepolis":{"count":59},"Cineworld":{"count":64},"Odeon":{"count":81}},"clinic":{"ФАП":{"count":162}},"dentist":{"Aspen Dental":{"count":73},"Consultorio Dental":{"count":187},"Dentista":{"count":109},"Family Dentistry":{"count":51},"Vitaldent":{"count":54},"Стоматолог":{"count":72},"Стоматологія":{"count":66}},"doctors":{"Háziorvosi rendelő":{"count":54},"Инвитро":{"count":115},"ФАП":{"count":147}},"driving_school":{"Автодром":{"count":55}},"fast_food":{"A&W":{"count":614},"Ali Baba":{"count":101},"Angel's Burger":{"count":66},"Antalya":{"count":53},"Arby's":{"count":1432},"Asia Bistro":{"count":53},"Asia Wok":{"count":53},"Baskin-Robbins":{"count":262,"tags":{"amenity":"ice_cream"}},"Bistro":{"count":80},"Bob's":{"count":83},"Bojangles":{"count":89},"Booster Juice":{"count":76},"Boston Market":{"count":107},"Braum's":{"count":58},"Burger King":{"count":6601,"tags":{"cuisine":"burger"}},"Burger Machine":{"count":55},"Büfé":{"count":72},"Captain D's":{"count":56},"Carl's Jr.":{"count":593,"tags":{"cuisine":"burger"}},"Checkers":{"count":102},"Chick-fil-A":{"count":906,"tags":{"cuisine":"chicken"}},"Chicken Express":{"count":67},"Chipotle":{"count":688,"tags":{"cuisine":"mexican"}},"Chowking":{"count":250},"Church's Chicken":{"count":249},"CoCo壱番屋":{"count":218},"Cold Stone Creamery":{"count":72},"Cook Out":{"count":81},"Culver's":{"count":541},"DQ":{"count":66},"Dairy Queen":{"count":1485},"Del Taco":{"count":244},"Ditsch":{"count":55},"Domino's Pizza":{"count":2577,"tags":{"cuisine":"pizza"}},"Dunkin' Donuts":{"count":747,"tags":{"cuisine":"donut"}},"El Pollo Loco":{"count":132},"Everest":{"count":59},"Extreme Pita":{"count":58},"Fazoli's":{"count":53},"Firehouse Subs":{"count":147},"Fish & Chips":{"count":185},"Fish and Chips":{"count":55},"Five Guys":{"count":457},"Food Court":{"count":72},"Greenwich":{"count":83},"Habib's":{"count":87},"Hallo Pizza":{"count":98},"Hardee's":{"count":634,"tags":{"cuisine":"burger"}},"Harvey's":{"count":158},"Hesburger":{"count":164},"Hungry Jacks":{"count":261,"tags":{"cuisine":"burger"}},"In-N-Out Burger":{"count":211},"Istanbul":{"count":96},"Istanbul Kebab":{"count":59},"Jack in the Box":{"count":951,"tags":{"cuisine":"burger"}},"Jamba Juice":{"count":148},"Jersey Mike's Subs":{"count":88},"Jimmy John's":{"count":519,"tags":{"cuisine":"sandwich"}},"Jollibee":{"count":740},"KFC":{"count":6003,"tags":{"cuisine":"chicken"}},"KFC/Taco Bell":{"count":70},"Kebab House":{"count":74},"Kebabai":{"count":64},"Kiosk":{"count":62},"Kochlöffel":{"count":78},"Kotipizza":{"count":89},"Krispy Kreme":{"count":63},"Krystal":{"count":53},"Little Caesars":{"count":567},"Little Caesars Pizza":{"count":82},"Long John Silver's":{"count":200},"Lotteria":{"count":67},"Max":{"count":54},"McDonald's":{"count":18327,"tags":{"cuisine":"burger"}},"Minute Burger":{"count":53},"Mr. Sub":{"count":153},"New York Pizza":{"count":65},"Nordsee":{"count":198},"Panda Express":{"count":593,"tags":{"cuisine":"chinese"}},"Panera Bread":{"count":120},"Papa John's":{"count":820,"tags":{"cuisine":"pizza"}},"Papa Murphy's":{"count":100},"Pinulito":{"count":58},"Pita Pit":{"count":150},"Pizza Hut":{"count":1503,"tags":{"cuisine":"pizza"}},"Pizza Hut Delivery":{"count":70},"Pizza King":{"count":56},"Pizza Nova":{"count":90},"Pizza Pizza":{"count":411},"Pollo Campero":{"count":134},"Pollo Granjero":{"count":66},"Popeye's":{"count":521,"tags":{"cuisine":"chicken"}},"Popeyes Louisiana Kitchen":{"count":51},"Qdoba":{"count":91},"Quick":{"count":434},"Quiznos":{"count":401},"Rally's":{"count":68},"Red Rooster":{"count":192},"Sbarro":{"count":65},"Schlotzsky's Deli":{"count":348},"Sibylla":{"count":74},"Sonic":{"count":1166,"tags":{"cuisine":"burger"}},"Starbucks":{"count":60,"tags":{"cuisine":"coffee_shop"}},"Steers":{"count":190},"Subway":{"count":11431},"Taco Bell":{"count":2947,"tags":{"cuisine":"mexican"}},"Taco Bueno":{"count":59},"Taco Cabana":{"count":57},"Taco Del Mar":{"count":57},"Taco John's":{"count":141},"Taco Time":{"count":171},"Telepizza":{"count":323},"Thai Express":{"count":63},"The Pizza Company":{"count":62},"Waffle House":{"count":86},"Wendy's":{"count":3036,"tags":{"cuisine":"burger"}},"Whataburger":{"count":815},"White Castle":{"count":149},"Wienerschnitzel":{"count":61},"Wimpy":{"count":168},"Zaxby's":{"count":185},"Γρηγόρης":{"count":59},"Бистро":{"count":61},"Бургер Кинг":{"count":181},"Крошка Картошка":{"count":77},"Макдоналдс":{"count":469,"tags":{"name:en":"McDonald's"}},"Робин Сдобин":{"count":131},"Русский Аппетит":{"count":129},"Сабвэй":{"count":73},"Стардог!s":{"count":66},"Теремок":{"count":155},"Шаверма":{"count":93},"Шаурма":{"count":265},"かっぱ寿司":{"count":84},"かつや":{"count":58},"くら寿司":{"count":99},"すき家":{"count":571,"tags":{"name:en":"SUKIYA"}},"なか卯":{"count":180},"ほっかほっか亭":{"count":57},"ほっともっと":{"count":168},"オリジン弁当":{"count":93},"ケンタッキーフライドチキン":{"count":334,"tags":{"cuisine":"chicken","name:en":"KFC"}},"サブウェイ":{"count":74},"スシロー":{"count":94},"マクドナルド":{"count":1261,"tags":{"cuisine":"burger","name:en":"McDonald's"}},"ミスタードーナツ":{"count":188},"モスバーガー":{"count":507,"tags":{"name:en":"MOS BURGER"}},"ロッテリア":{"count":97},"丸亀製麺":{"count":57},"吉野家":{"count":461},"幸楽苑":{"count":80},"摩斯漢堡":{"count":86},"松屋":{"count":574,"tags":{"name:en":"Matsuya"}},"肯德基":{"count":197},"麥當勞":{"count":224},"麦当劳":{"count":97},"롯데리아":{"count":83}},"fuel":{"76":{"count":603},"1-2-3":{"count":75},"7-Eleven":{"count":1013},"ABC":{"count":83},"ADNOC":{"count":76},"ANP":{"count":202},"ARAL":{"count":68},"Aegean":{"count":56},"Afriquia":{"count":134},"Agip":{"count":2348},"Agrola":{"count":99},"Alon":{"count":54},"Alpet":{"count":61},"Api":{"count":234},"Aral":{"count":1708},"Arco":{"count":585},"Asda":{"count":51},"Auchan":{"count":84},"Avanti":{"count":112},"Avia":{"count":1061},"BEBECO":{"count":77},"BFT":{"count":102},"BHPetrol":{"count":60},"BP":{"count":4069},"BR":{"count":165},"Bangchak":{"count":106},"Benzina":{"count":167},"Bharat Petroleum":{"count":230},"Bliska":{"count":141},"CAMPSA":{"count":420},"CARREFOUR":{"count":61},"CEPSA":{"count":892},"CNG":{"count":373},"Caltex":{"count":1574},"Campsa":{"count":64},"Canadian Tire":{"count":97},"Carrefour":{"count":372},"Casey's General Store":{"count":385},"Cenex":{"count":222},"Cepsa":{"count":305},"Ceypetco":{"count":70},"Chevron":{"count":1781},"Circle K":{"count":730},"Citgo":{"count":692},"Clark":{"count":56},"Co-op":{"count":52},"Coles Express":{"count":305},"Conoco":{"count":398},"Coop":{"count":71},"Copec":{"count":566},"Copetrol":{"count":119},"Cosmo":{"count":68},"Costco":{"count":82},"Costco Gas":{"count":62},"Costco Gasoline":{"count":59},"Couche-Tard":{"count":54},"Crodux":{"count":51},"Cumberland Farms":{"count":93},"Delta":{"count":157},"Diamond Shamrock":{"count":51},"Drummed Fuel":{"count":178},"E. Leclerc":{"count":136},"EKO":{"count":224},"ENEOS":{"count":1600},"ENI":{"count":92},"ERG":{"count":71},"Elan":{"count":208},"Eneos":{"count":130},"Engen":{"count":383},"Eni":{"count":681},"Erg":{"count":469},"Esso":{"count":4742},"Esso Express":{"count":176},"EuroOil":{"count":52},"Exxon":{"count":1064},"F24":{"count":67},"Firezone":{"count":66},"Flying V":{"count":175},"GALP":{"count":788},"GNV":{"count":58},"Gas":{"count":66},"Gazprom":{"count":68},"GetGo":{"count":54},"Goil":{"count":78},"Gulf":{"count":416},"H-E-B Fuel":{"count":51},"H-E-B Gas":{"count":155},"HEM":{"count":276},"HP":{"count":163},"HP Petrol Pump":{"count":53},"Helios":{"count":63},"Hess":{"count":195},"Hindustan Petroleum":{"count":82},"Holiday":{"count":156},"Husky":{"count":244},"IES":{"count":57},"IP":{"count":993},"Independent Fuel Station":{"count":52},"Indian Oil":{"count":416},"Indipend.":{"count":129},"Ingo":{"count":62},"Intermarché":{"count":556},"Intermarché Super":{"count":102},"Ipiranga":{"count":173},"Irving":{"count":194},"JA-SS":{"count":74},"JOMO":{"count":51},"Jet":{"count":707},"Jetti":{"count":61},"Kangaroo":{"count":115},"Kobil":{"count":87},"Kroger":{"count":59},"Kroger Fuel":{"count":68},"Kum & Go":{"count":136},"Kwik Trip":{"count":210},"LPG":{"count":349},"LPG Station":{"count":51},"LUKOIL":{"count":61},"Liberty":{"count":93},"Lotos":{"count":284},"Lotos Optima":{"count":71},"Love's":{"count":52},"Lukoil":{"count":908},"MEROIL":{"count":70},"MOL":{"count":436},"MRS":{"count":65},"Marathon":{"count":694},"Maverik":{"count":66},"Maxol":{"count":57},"Metano":{"count":248},"Migrol":{"count":71},"Minipump":{"count":140},"Mobil":{"count":1387},"Mobile":{"count":62},"Mol":{"count":64},"Morrisons":{"count":128},"Moya":{"count":62},"Murphy USA":{"count":190},"NP":{"count":63},"Neste":{"count":166},"OIL!":{"count":110},"OK":{"count":269},"OKQ8":{"count":218},"OMV":{"count":936},"Oilibya":{"count":127},"Opet":{"count":117},"Orlen":{"count":1185},"PETRONOR":{"count":182},"PSO":{"count":121},"PSO Petrol Pump":{"count":56},"PT":{"count":306},"PTT":{"count":423},"PV Oil":{"count":100},"Pacific Pride":{"count":54},"Pecsa":{"count":130},"Pemex":{"count":2023},"Pertamina":{"count":324},"Petro":{"count":54},"Petro-Canada":{"count":893},"Petrobras":{"count":487},"Petrochina":{"count":116},"Petroecuador":{"count":64},"Petrol Ofisi":{"count":237},"Petrolimex":{"count":325},"Petrom":{"count":381},"Petron":{"count":1485},"Petronas":{"count":387},"Petroperu":{"count":110},"Phillips 66":{"count":424},"Phoenix":{"count":210},"Pilot":{"count":69},"Pioneer":{"count":104},"Posto":{"count":52},"Posto Atem":{"count":68},"Posto BR":{"count":222},"Posto Ipiranga":{"count":177},"Posto Shell":{"count":104},"Primax":{"count":288},"Prio":{"count":52},"Puma":{"count":442},"Q1":{"count":53},"Q8":{"count":1467},"Q8 Easy":{"count":66},"QuikTrip":{"count":251},"REPSOL":{"count":1380},"RaceTrac":{"count":80},"Raiffeisenbank":{"count":130},"Repsol":{"count":1099},"Rompetrol":{"count":234},"Royal Farms":{"count":79},"Rubis":{"count":108},"SB Tank":{"count":62},"SPBU":{"count":203},"Safeway":{"count":74},"Sainsbury's":{"count":75},"Sam's Club":{"count":57},"Sasol":{"count":90},"Sea Oil":{"count":142},"Sheetz":{"count":304},"Shell":{"count":12317},"Shell Express":{"count":135},"Sinclair":{"count":201},"Sinopec":{"count":106},"Sinopec Fuel":{"count":116},"Slovnaft":{"count":259},"Socar":{"count":86},"Sokimex":{"count":85},"Speedway":{"count":556},"St1":{"count":141},"Star":{"count":419},"Star Oil":{"count":100},"Station Service E. Leclerc":{"count":423},"Statoil":{"count":495},"Stewart's":{"count":72},"Sunoco":{"count":853},"Super U":{"count":174},"Tamoil":{"count":959},"Tango":{"count":146},"Teboil":{"count":100},"Tela":{"count":191},"Terpel":{"count":367},"Tesco":{"count":218},"Texaco":{"count":1167},"Tinq":{"count":219},"Topaz":{"count":111},"Total":{"count":3591},"Total Access":{"count":226},"Total Erg":{"count":59},"TotalErg":{"count":267},"Turkey Hill":{"count":80},"Turmöl":{"count":80},"Ultramar":{"count":372},"United":{"count":197},"Uno":{"count":134},"Uno-X":{"count":69},"Valero":{"count":778},"Vito":{"count":91},"WOG":{"count":350},"Wawa":{"count":173},"Westfalen":{"count":94},"Woolworths Petrol":{"count":187},"Z":{"count":98},"bft":{"count":202},"eni":{"count":71},"ΕΚΟ":{"count":58},"АГЗС":{"count":1020},"АЗС":{"count":86},"Авіас":{"count":116},"БРСМ-Нафта":{"count":64},"Башнефть":{"count":272},"Белоруснефть":{"count":71},"Газовая заправка":{"count":57},"Газпромнефть":{"count":1242},"Гелиос":{"count":61},"ЕКА":{"count":78},"Заправка":{"count":63},"КазМунайГаз":{"count":150},"Лукойл":{"count":2327},"Макпетрол":{"count":108},"НК Альянс":{"count":105},"Нефтьмагистраль":{"count":66},"ОККО":{"count":316},"ОМВ":{"count":55},"Октан":{"count":53},"ПТК":{"count":104},"Петрол":{"count":124},"Пропан":{"count":83},"Роснефть":{"count":957},"Сибнефть":{"count":51},"Сургутнефтегаз":{"count":95},"ТНК":{"count":588},"Татнефтепродукт":{"count":58},"Татнефть":{"count":331},"Укрнафта":{"count":228},"דור אלון":{"count":126},"דלק":{"count":160},"סונול":{"count":159},"פז":{"count":209},"محطة وقود":{"count":221},"محطه وقود":{"count":98},"پمپ بنزین":{"count":559},"پمپ گاز":{"count":152},"บางจาก":{"count":214},"ป.ต.ท.":{"count":414},"เชลล์":{"count":90},"เอสโซ่":{"count":82},"エッソ":{"count":70},"エネオス":{"count":301},"コスモ石油":{"count":415},"ゼネラル":{"count":75},"中国石化":{"count":104},"中国石化 Sinopec":{"count":61},"中国石油":{"count":82},"中油":{"count":64},"出光":{"count":620,"tags":{"name:en":"IDEMITSU"}},"加油站":{"count":60},"台灣中油":{"count":257},"昭和シェル":{"count":274}},"hospital":{"Cruz Roja":{"count":93},"IMSS":{"count":64},"Инфекционное отделение":{"count":91},"Кожно-венерологический диспансер":{"count":57},"Районная больница":{"count":88},"Роддом":{"count":133},"Родильный дом":{"count":75},"Скорая помощь":{"count":75},"ФАП":{"count":108},"ЦРБ":{"count":122},"Центральная районная больница":{"count":144},"โรงพยาบาลส่งเสริมสุขภาพตำบล":{"count":69}},"ice_cream":{"Baskin-Robbins":{"count":69,"tags":{"amenity":"ice_cream"}},"Cold Stone Creamery":{"count":66},"Grido":{"count":163}},"kindergarten":{"Amado Nervo":{"count":64},"Anganwadi":{"count":85},"Arche Noah":{"count":67},"Benito Juarez":{"count":89},"CONAFE Preescolar":{"count":90},"Cuauhtemoc":{"count":54},"Cursos Comunitarios":{"count":74},"Educacion Inicial de CONAFE No Escolarizado":{"count":184},"Emiliano Zapata":{"count":60},"Estefania Casta�eda":{"count":53},"Evangelischer Kindergarten":{"count":320},"Federico Froebel":{"count":88},"Gabriela Mistral":{"count":129},"Jardin Infantil":{"count":85},"Jean Piaget":{"count":82},"Jose Vasconcelos":{"count":71},"Juan Escutia":{"count":82},"Katholischer Kindergarten":{"count":99},"Kindergarten Regenbogen":{"count":62},"Kindergarten St. Josef":{"count":55},"Kindergarten St. Martin":{"count":55},"Maria Montessori":{"count":93},"Miguel Hidalgo Y Costilla":{"count":57},"Ni�os Heroes":{"count":68},"PAUD":{"count":82},"Pusteblume":{"count":54},"Rosaura Zapata":{"count":68},"Sor Juana Ines De La Cruz":{"count":76},"Spatzennest":{"count":54},"Städtischer Kindergarten":{"count":103},"Villa Kunterbunt":{"count":88},"Waldkindergarten":{"count":111},"Waldorfkindergarten":{"count":71},"Óvoda":{"count":72},"Детсад":{"count":65},"Детский сад \"Солнышко\"":{"count":83},"Детский сад № 1":{"count":54},"Детский сад №1":{"count":150},"Детский сад №10":{"count":77},"Детский сад №11":{"count":81},"Детский сад №12":{"count":57},"Детский сад №13":{"count":57},"Детский сад №14":{"count":76},"Детский сад №15":{"count":72},"Детский сад №16":{"count":58},"Детский сад №17":{"count":67},"Детский сад №18":{"count":77},"Детский сад №19":{"count":62},"Детский сад №2":{"count":155},"Детский сад №22":{"count":60},"Детский сад №24":{"count":53},"Детский сад №25":{"count":56},"Детский сад №27":{"count":54},"Детский сад №29":{"count":57},"Детский сад №3":{"count":129},"Детский сад №33":{"count":55},"Детский сад №4":{"count":86},"Детский сад №5":{"count":106},"Детский сад №6":{"count":93},"Детский сад №7":{"count":98},"Детский сад №8":{"count":80},"Детский сад №9":{"count":80},"Дитячий садок":{"count":58},"Сказка":{"count":52},"Солнышко":{"count":99},"Теремок":{"count":59},"საბავშვო ბაღი":{"count":69},"中央保育所":{"count":56}},"library":{"Biblioteca Comunale":{"count":212},"Biblioteca Municipal":{"count":451},"Biblioteca Pública":{"count":66},"Biblioteca Pública Municipal":{"count":85},"Biblioteca comunale":{"count":187},"Biblioteka Publiczna":{"count":78},"Bibliothèque Municipale":{"count":299},"Bibliothèque municipale":{"count":247},"Bücherei":{"count":113},"Central Library":{"count":65},"Gemeindebücherei":{"count":150},"Gminna Biblioteka Publiczna":{"count":71},"Miejska Biblioteka Publiczna":{"count":66},"Médiathèque":{"count":287},"Městská knihovna":{"count":60},"Public Library":{"count":91},"Stadtbibliothek":{"count":232},"Stadtbücherei":{"count":289},"Городская библиотека":{"count":69},"Детская библиотека":{"count":260},"Центральная библиотека":{"count":83},"Центральная городская библиотека":{"count":61},"图书馆":{"count":65}},"pharmacy":{"36.6":{"count":57},"Adler Apotheke":{"count":375},"Alte Apotheke":{"count":99},"Apollo Pharmacy":{"count":87},"Apotek":{"count":62},"Apotek Hjärtat":{"count":51},"Apotheke am Markt":{"count":83},"Bahnhof Apotheke":{"count":51},"Bahnhof-Apotheke":{"count":90},"Bartell Drugs":{"count":53},"Benavides":{"count":83},"Benu":{"count":61},"Boots":{"count":1348},"Botica":{"count":118},"Brunnen-Apotheke":{"count":77},"Burg-Apotheke":{"count":76},"Bären-Apotheke":{"count":111},"CVS":{"count":3228},"Camelia":{"count":54},"Catena":{"count":112},"Chemist Warehouse":{"count":82},"Clicks":{"count":123},"Cruz Azul":{"count":97},"Cruz Verde":{"count":223},"Dbam o Zdrowie":{"count":68},"Dr. Max":{"count":324},"Droga Raia":{"count":152},"Drogaria São Paulo":{"count":87},"Drogasil":{"count":157},"Duane Reade":{"count":91},"Eczane":{"count":88},"Engel-Apotheke":{"count":143},"Eurovaistinė":{"count":89},"Familiprix":{"count":70},"Farmacenter":{"count":65},"Farmacia Centrale":{"count":61},"Farmacia Comunale":{"count":196},"Farmacia Guadalajara":{"count":146},"Farmacia del Ahorro":{"count":65},"Farmacias Ahumada":{"count":182},"Farmacias Cruz Azul":{"count":134},"Farmacias Cruz Verde":{"count":162},"Farmacias Económicas":{"count":63},"Farmacias Guadalajara":{"count":107},"Farmacias SalcoBrand":{"count":140},"Farmacias Sana Sana":{"count":111},"Farmacias Similares":{"count":137},"Farmacias del Ahorro":{"count":187},"Farmacity":{"count":191},"Farmahorro":{"count":53},"Farmatodo":{"count":165},"Farmácia":{"count":85},"Felicia":{"count":56},"Fybeca":{"count":52},"Generika Drugstore":{"count":52},"Gintarinė vaistinė":{"count":121},"Guardian":{"count":71},"Gyógyszertár":{"count":59},"H-E-B Pharmacy":{"count":239},"Hirsch-Apotheke":{"count":180},"Hubertus Apotheke":{"count":120},"Inkafarma":{"count":234},"Jean Coutu":{"count":132},"Kinney Drugs":{"count":74},"Kur-Apotheke":{"count":52},"Linden-Apotheke":{"count":224},"Ljekarna":{"count":77},"Lloyds Pharmacy":{"count":539},"Lékárna":{"count":52},"Löwen-Apotheke":{"count":397},"Marien-Apotheke":{"count":370},"Markt-Apotheke":{"count":207},"Mercury Drug":{"count":584},"Mifarma":{"count":195},"Mēness aptieka":{"count":64},"Neue Apotheke":{"count":129},"Pague Menos":{"count":74},"Panvel":{"count":77},"Park-Apotheke":{"count":54},"Pharmacie Centrale":{"count":218},"Pharmacie Principale":{"count":62},"Pharmacie de l'Hôtel de Ville":{"count":52},"Pharmacie de la Gare":{"count":114},"Pharmacie de la Mairie":{"count":71},"Pharmacie de la Poste":{"count":68},"Pharmacie du Centre":{"count":154},"Pharmacie du Marché":{"count":110},"Pharmacie du Parc":{"count":60},"Pharmaprix":{"count":99},"Pharmasave":{"count":129},"Punkt Apteczny":{"count":53},"Rathaus-Apotheke":{"count":181},"Rats-Apotheke":{"count":126},"Rexall":{"count":109},"Rite Aid":{"count":1481},"Rose Pharmacy":{"count":99},"Rosen-Apotheke":{"count":205},"Rowlands Pharmacy":{"count":127},"SalcoBrand":{"count":112},"Sana Sana":{"count":95},"Schloss-Apotheke":{"count":62},"Sensiblu":{"count":115},"Shoppers Drug Mart":{"count":713},"Sonnen-Apotheke":{"count":372},"South Star Drug":{"count":69},"Stadt-Apotheke":{"count":397},"Stern-Apotheke":{"count":83},"Superdrug":{"count":177},"São João":{"count":54},"The Generics Pharmacy":{"count":211},"Uniprix":{"count":63},"Walgreens":{"count":3314},"Walgreens Pharmacy":{"count":76},"Walmart Pharmacy":{"count":99},"Watsons":{"count":110},"Well Pharmacy":{"count":61},"centro naturista":{"count":123},"А5":{"count":94},"Айболит":{"count":88},"Аптека 36,6":{"count":285},"Аптека низких цен":{"count":65},"Аптека низьких цін":{"count":88},"Аптека от склада":{"count":83},"Аптека №1":{"count":92},"Аптечный пункт":{"count":285},"Арніка":{"count":124},"Бережная аптека":{"count":67},"Будь здоров":{"count":63},"Вита":{"count":140},"Горздрав":{"count":395},"Живика":{"count":105},"Здоровье":{"count":87},"Имплозия":{"count":84},"Классика":{"count":102},"Ладушка":{"count":53},"Мед-сервіс":{"count":59},"Мелодия здоровья":{"count":60},"Невис":{"count":151},"Норма":{"count":89},"Озерки":{"count":54},"Панацея":{"count":68},"Первая помощь":{"count":132},"Планета здоровья":{"count":140},"Радуга":{"count":139},"Ригла":{"count":215},"Семейная":{"count":52},"Социальная аптека":{"count":62},"Столички":{"count":83},"Фармакопейка":{"count":85},"Фармакор":{"count":106},"Фармация":{"count":187},"Фармленд":{"count":108},"Центральная аптека":{"count":57},"סופר-פארם":{"count":93},"داروخانه":{"count":264},"داروخانه شبانه روزی":{"count":54},"صيدلية":{"count":148},"くすりの福太郎":{"count":51},"さくら薬局":{"count":52},"ウエルシア":{"count":84},"カワチ薬品":{"count":52},"クリエイト":{"count":53},"サンドラッグ":{"count":130},"スギ薬局":{"count":134},"セイジョー":{"count":58},"ツルハドラッグ":{"count":185},"ドラッグてらしま (Drug Terashima)":{"count":58},"マツモトキヨシ":{"count":221},"丁丁藥局":{"count":75}},"pub":{"Black Bull":{"count":55},"Commercial Hotel":{"count":62},"Cross Keys":{"count":64},"Irish Pub":{"count":107},"Kings Arms":{"count":81},"Kings Head":{"count":65},"New Inn":{"count":100},"Prince of Wales":{"count":89},"Queens Head":{"count":55},"Red Lion":{"count":201},"Rose & Crown":{"count":63},"Rose and Crown":{"count":82},"Royal Hotel":{"count":64},"Royal Oak":{"count":172},"The Albion":{"count":51},"The Anchor":{"count":68},"The Angel":{"count":55},"The Beehive":{"count":52},"The Bell":{"count":128},"The Bell Inn":{"count":58},"The Black Horse":{"count":100},"The Bull":{"count":82},"The Castle":{"count":63},"The Chequers":{"count":74},"The Cricketers":{"count":56},"The Cross Keys":{"count":58},"The Crown":{"count":252},"The Crown Inn":{"count":88},"The Fox":{"count":76},"The George":{"count":119},"The Green Man":{"count":59},"The Greyhound":{"count":99},"The Kings Arms":{"count":65},"The Kings Head":{"count":68},"The New Inn":{"count":126},"The Plough":{"count":182},"The Plough Inn":{"count":57},"The Queens Head":{"count":61},"The Railway":{"count":112},"The Red Lion":{"count":271},"The Rising Sun":{"count":74},"The Royal Oak":{"count":223},"The Ship":{"count":92},"The Ship Inn":{"count":98},"The Star":{"count":72},"The Star Inn":{"count":53},"The Sun Inn":{"count":51},"The Swan":{"count":155},"The Swan Inn":{"count":59},"The Victoria":{"count":72},"The Wheatsheaf":{"count":126},"The White Hart":{"count":247},"The White Horse":{"count":234},"The White Lion":{"count":75},"The White Swan":{"count":55},"魚民":{"count":119},"鳥貴族":{"count":57}},"restaurant":{"Adler":{"count":228},"Adria":{"count":60},"Adyar Ananda Bhavan":{"count":60},"Akropolis":{"count":212},"Ali Baba":{"count":59},"Alte Post":{"count":68},"Applebee's":{"count":977},"Asia":{"count":78},"Athen":{"count":75},"Athos":{"count":61},"Autogrill":{"count":60},"Bahnhof":{"count":56},"Bella Italia":{"count":194},"Bella Napoli":{"count":88},"Belvedere":{"count":55},"Big Boy":{"count":58},"Bistro":{"count":64},"Bob Evans":{"count":269},"Bonefish Grill":{"count":73},"Boston Market":{"count":91},"Boston Pizza":{"count":278},"Buffalo Grill":{"count":282},"Buffalo Wild Wings":{"count":454},"Bären":{"count":75},"Cafeteria":{"count":65},"California Pizza Kitchen":{"count":116},"Campanile":{"count":55},"Canteen":{"count":91},"Capri":{"count":56},"Captain D's":{"count":54},"Carluccio's":{"count":57},"Carpe Diem":{"count":60},"Carrabba's Italian Grill":{"count":62},"Casa Mia":{"count":64},"Casablanca":{"count":61},"Cheesecake Factory":{"count":52},"Chifa":{"count":86},"Chili's":{"count":698},"China Buffet":{"count":54},"China Garden":{"count":114},"China House":{"count":72},"China Town":{"count":117},"China Wok":{"count":100},"Chiquito":{"count":55},"Chuck E. Cheese's":{"count":54},"Cici's Pizza":{"count":51},"CoCo壱番屋":{"count":77},"Cold Stone Creamery":{"count":67},"Comedor":{"count":60},"Comida China":{"count":52},"Courtepaille":{"count":170},"Cracker Barrel":{"count":392},"Da Grasso":{"count":63},"Da Vinci":{"count":88},"Delphi":{"count":105},"Denny's":{"count":850},"Deutsches Haus":{"count":93},"Dionysos":{"count":75},"Dolce Vita":{"count":121},"Dorfkrug":{"count":60},"Dunkin' Donuts":{"count":94,"tags":{"cuisine":"donut"}},"East Side Mario's":{"count":53},"El Greco":{"count":112},"El Paso":{"count":60},"El Rancho":{"count":82},"Europa":{"count":61},"Famous Dave's":{"count":62},"Firehouse Subs":{"count":85},"Five Guys":{"count":91},"Flunch":{"count":179},"Food Court":{"count":52},"Frankie & Benny's":{"count":151},"Friendly's":{"count":113},"Gasthaus Krone":{"count":93},"Gasthaus zur Linde":{"count":59},"Gasthof zur Post":{"count":109},"Golden Corral":{"count":209},"Golden Dragon":{"count":62},"Great Wall":{"count":54},"Grüner Baum":{"count":122},"Gusto":{"count":74},"Hard Rock Cafe":{"count":96},"Hardee's":{"count":56,"tags":{"cuisine":"burger"}},"Harvester":{"count":75},"Hellas":{"count":66},"Hippopotamus":{"count":115},"Hirsch":{"count":83},"Hirschen":{"count":86},"Hong Kong":{"count":126},"Hooters":{"count":190},"IHOP":{"count":758},"IL Патио":{"count":51},"Jason's Deli":{"count":73},"Jimmy John's":{"count":150,"tags":{"cuisine":"sandwich"}},"Joe's Crab Shack":{"count":70},"Jägerhof":{"count":54},"Kantine":{"count":104},"Kelsey's":{"count":66},"Kirchenwirt":{"count":94},"Kreta":{"count":70},"Kreuz":{"count":85},"Krone":{"count":179},"Kudu":{"count":172},"L'Escale":{"count":66},"L'Osteria":{"count":80},"La Bodega":{"count":55},"La Boucherie":{"count":80},"La Cantina":{"count":105},"La Casa":{"count":66},"La Casona":{"count":62},"La Dolce Vita":{"count":129},"La Fontana":{"count":62},"La Gondola":{"count":60},"La Hacienda":{"count":54},"La Pataterie":{"count":116},"La Pergola":{"count":87},"La Perla":{"count":85},"La Piazza":{"count":123},"La Piazzetta":{"count":77},"La Place":{"count":55},"La Scala":{"count":62},"La Strada":{"count":74},"La Tagliatella":{"count":69},"La Tasca":{"count":56},"La Taverna":{"count":58},"La Terrasse":{"count":82},"La Terraza":{"count":56},"La Terrazza":{"count":57},"La Trattoria":{"count":91},"Lamm":{"count":69},"Linde":{"count":114},"Lindenhof":{"count":95},"Little Caesars":{"count":80},"Little Chef":{"count":62},"Little Italy":{"count":90},"Logan's Roadhouse":{"count":89},"LongHorn Steakhouse":{"count":183},"Lotus":{"count":87},"Léon de Bruxelles":{"count":63},"Löwen":{"count":141},"MK Restaurants":{"count":65},"Maharaja":{"count":52},"Mamma Mia":{"count":130},"Mandarin":{"count":90},"Mang Inasal":{"count":128},"Marco Polo":{"count":62},"Marco's Pizza":{"count":53},"McAlister's Deli":{"count":51},"Mediterraneo":{"count":55},"Mellow Mushroom":{"count":73},"Mensa":{"count":148},"Milano":{"count":77},"Mimi's Cafe":{"count":52},"Moe's Southwest Grill":{"count":79},"Mykonos":{"count":89},"Mythos":{"count":61},"Nando's":{"count":412},"Noodles & Company":{"count":106},"O'Charley's":{"count":61},"Oasis":{"count":73},"Ocean Basket":{"count":71},"Ochsen":{"count":94},"Old Chicago":{"count":54},"Olive Garden":{"count":504},"Olympia":{"count":86},"Osaka":{"count":52},"Outback Steakhouse":{"count":399},"P.F. Chang's":{"count":53},"Pancake House":{"count":79},"Panda":{"count":52},"Panera Bread":{"count":582},"Panorama":{"count":102},"Papa Murphy's":{"count":66},"Parrilla":{"count":62},"Peking":{"count":68},"Perkins":{"count":157},"Pinocchio":{"count":63},"Pizza Express":{"count":417},"Pizza Factory":{"count":59},"Pizza House":{"count":56},"Pizza Hut":{"count":2688,"tags":{"cuisine":"pizza"}},"Pizza Ranch":{"count":77},"Pizzeria Italia":{"count":65},"Pizzeria Milano":{"count":51},"Pizzeria Napoli":{"count":53},"Pizzeria Roma":{"count":86},"Pizzeria Venezia":{"count":54},"Poivre Rouge":{"count":56},"Pollo Campero":{"count":53},"Pomodoro":{"count":62},"Portofino":{"count":67},"Poseidon":{"count":145},"Prezzo":{"count":147},"Qdoba":{"count":81},"Qdoba Mexican Grill":{"count":54},"Ratskeller":{"count":161},"Red Lobster":{"count":419},"Red Robin":{"count":312},"Restaurante Universitário":{"count":53},"Rhodos":{"count":94},"Ristorante Del Arte":{"count":160},"Roma":{"count":85},"Rose":{"count":51},"Round Table Pizza":{"count":100},"Ruby Tuesday":{"count":303},"Rössle":{"count":54},"Rössli":{"count":93},"Saigon":{"count":51},"Sakura":{"count":139},"San Marco":{"count":88},"Santorini":{"count":59},"Schwarzer Adler":{"count":65},"Schützenhaus":{"count":151},"Shakey's":{"count":64},"Shalimar":{"count":53},"Shanghai":{"count":96},"Shari's":{"count":75},"Shoney's":{"count":55},"Sizzler":{"count":90},"Sonic":{"count":80,"tags":{"cuisine":"burger"}},"Sonne":{"count":121},"Sphinx":{"count":66},"Sportheim":{"count":113},"Spur":{"count":70},"Starbucks":{"count":54,"tags":{"cuisine":"coffee_shop"}},"Steak 'n Shake":{"count":86,"tags":{"cuisine":"burger"}},"Steak House":{"count":58},"Sternen":{"count":85},"Subway":{"count":1108},"Sunset Grill":{"count":55},"Sushi":{"count":88},"Sushi Bar":{"count":68},"Swiss Chalet":{"count":162},"Syrtaki":{"count":65},"TGI Friday's":{"count":364},"Taj Mahal":{"count":183},"Taste of India":{"count":68},"Taverna":{"count":69},"Telepizza":{"count":109},"Texas Roadhouse":{"count":232},"The Cheesecake Factory":{"count":52},"Tim Hortons":{"count":61},"Toby Carvery":{"count":51},"Tony Roma's":{"count":63},"Toscana":{"count":76},"Trattoria":{"count":70},"Traube":{"count":68},"Vapiano":{"count":136},"Venezia":{"count":68},"Village Inn":{"count":149},"Vips":{"count":109},"Waffle House":{"count":521},"Wagamama":{"count":111},"Waldschänke":{"count":52},"Warung":{"count":73},"Wasabi":{"count":70},"Wimpy":{"count":66},"Zaxby's":{"count":60},"Zizzi":{"count":102},"Zorbas":{"count":62},"Zum Hirschen":{"count":52},"Zum Löwen":{"count":80},"Zur Krone":{"count":96},"Zur Linde":{"count":228},"Zur Post":{"count":125},"Zur Sonne":{"count":77},"Евразия":{"count":93},"Ресторан":{"count":60},"Тануки":{"count":62},"Якитория":{"count":84},"رستوران":{"count":72},"مطعم":{"count":52},"すき家":{"count":61,"tags":{"name:en":"SUKIYA"}},"はま寿司":{"count":67},"びっくりドンキー":{"count":120},"やよい軒":{"count":71},"ガスト":{"count":512,"tags":{"name:en":"Gusto"}},"ココス":{"count":142},"サイゼリア":{"count":54},"サイゼリヤ":{"count":285},"ジョイフル":{"count":83},"ジョナサン":{"count":139},"ジョリーパスタ":{"count":75},"デニーズ":{"count":199},"バーミヤン":{"count":130},"ロイヤルホスト":{"count":108},"丸亀製麺":{"count":98},"八方雲集":{"count":145},"吉野家":{"count":61},"夢庵":{"count":67},"大戸屋":{"count":68},"大阪王将":{"count":68},"天下一品":{"count":70},"安楽亭":{"count":60},"牛角":{"count":107},"食堂":{"count":63},"餃子の王将":{"count":212},"바다횟집 (Bada Fish Restaurant)":{"count":52}},"school":{"Adolfo Lopez Mateos":{"count":137},"Agustin Ya�ez":{"count":57},"Albert-Schweitzer-Schule":{"count":81},"Amado Nervo":{"count":85},"Astrid-Lindgren-Schule":{"count":77},"Benito Juarez":{"count":294},"Brown School":{"count":54},"CEM":{"count":215},"Center School":{"count":115},"Central Elementary School":{"count":179},"Central High School":{"count":130},"Central School":{"count":215},"Colegio San José":{"count":74},"Collège Jean Moulin":{"count":68},"Collège privé Saint-Joseph":{"count":60},"Cuauhtemoc":{"count":152},"Curso Comunitario":{"count":57},"Cursos Comunitarios":{"count":116},"EPP":{"count":112},"Emiliano Zapata":{"count":286},"Escola Estadual":{"count":73},"Escola Municipal":{"count":211},"Fairview Elementary School":{"count":64},"Fairview School":{"count":164},"Francisco I Madero":{"count":86},"Francisco I. Madero":{"count":52},"Francisco Villa":{"count":116},"Franklin Elementary School":{"count":96},"Franklin School":{"count":126},"Garfield Elementary School":{"count":69},"Garfield School":{"count":58},"Gimnazjum nr 1":{"count":59},"Government School":{"count":60},"Gregorio Torres Quintero":{"count":53},"Groupe Scolaire":{"count":57},"Guadalupe Victoria":{"count":58},"Highland School":{"count":71},"Hillcrest Elementary School":{"count":63},"Holy Cross School":{"count":68},"Holy Family School":{"count":77},"Holy Trinity School":{"count":59},"Ignacio Allende":{"count":51},"Ignacio Zaragoza":{"count":98},"Immaculate Conception School":{"count":83},"Jackson Elementary School":{"count":53},"Jackson School":{"count":56},"Jefferson Elementary School":{"count":177},"Jefferson School":{"count":108},"Jose Clemente Orozco":{"count":59},"Jose Ma Morelos Y Pavon":{"count":120},"Jose Vasconcelos":{"count":73},"Josefa Ortiz De Dominguez":{"count":78},"Juan Escutia":{"count":121},"Justo Sierra":{"count":118},"Kumon":{"count":66},"Lazaro Cardenas":{"count":68},"Lazaro Cardenas Del Rio":{"count":153},"Leona Vicario":{"count":64},"Liberty Elementary School":{"count":56},"Liberty School":{"count":84},"Lincoln Elementary School":{"count":264},"Lincoln School":{"count":269},"Longfellow Elementary School":{"count":55},"Longfellow School":{"count":53},"Madison Elementary School":{"count":55},"Manuel Lopez Cotilla":{"count":107},"Maple Grove School":{"count":51},"McKinley Elementary School":{"count":62},"McKinley School":{"count":63},"Miguel Hidalgo":{"count":86},"Miguel Hidalgo Y Costilla":{"count":213},"Miller School":{"count":66},"Mount Pleasant School":{"count":61},"Mount Zion School":{"count":53},"Mountain View Elementary School":{"count":52},"New Hope School":{"count":51},"Nicolas Bravo":{"count":58},"Ni�os Heroes":{"count":155},"Nombre En Tramite":{"count":126},"North Elementary School":{"count":57},"Oak Grove School":{"count":148},"Pedro Moreno":{"count":69},"Pestalozzischule":{"count":84},"Pine Grove School":{"count":63},"Pleasant Hill School":{"count":110},"Pleasant Valley School":{"count":85},"Pleasant View School":{"count":61},"Primaria Comunitaria":{"count":59},"Ramon Corona":{"count":54},"Ricardo Flores Magon":{"count":91},"Riverside School":{"count":76},"Roosevelt Elementary School":{"count":112},"Roosevelt School":{"count":114},"SD":{"count":76},"SDN":{"count":290},"Sacred Heart School":{"count":206},"Saint Francis School":{"count":56},"Saint James School":{"count":83},"Saint Johns School":{"count":173},"Saint Joseph School":{"count":147},"Saint Josephs School":{"count":157},"Saint Kizito Primary School":{"count":61},"Saint Mary School":{"count":54},"Saint Marys School":{"count":256},"Saint Patricks School":{"count":80},"Saint Paul School":{"count":53},"Saint Pauls School":{"count":74},"Saint Peters School":{"count":81},"Schillerschule":{"count":61},"School Number 1":{"count":233},"School Number 2":{"count":206},"School Number 3":{"count":184},"School Number 4":{"count":126},"Smith School":{"count":60},"Sor Juana Ines De La Cruz":{"count":56},"South Elementary School":{"count":53},"Sunnyside School":{"count":60},"Szkoła Podstawowa nr 1":{"count":78},"Szkoła Podstawowa nr 2":{"count":75},"Szkoła Podstawowa nr 3":{"count":60},"Trinity School":{"count":85},"UNIDAD EDUCATIVA":{"count":106},"Union School":{"count":128},"Valentin Gomez Farias":{"count":71},"Venustiano Carranza":{"count":64},"Vicente Guerrero":{"count":159},"Volkshochschule":{"count":105},"Volksschule":{"count":366},"Washington Elementary School":{"count":192},"Washington School":{"count":213},"West Elementary School":{"count":58},"White School":{"count":51},"Wilson Elementary School":{"count":66},"Wilson School":{"count":80},"Általános iskola":{"count":105},"École Jules Ferry":{"count":51},"École Notre-Dame":{"count":61},"École Saint-Joseph":{"count":96},"École primaire Jean Jaurès":{"count":71},"École primaire Jules Ferry":{"count":82},"École primaire privée Notre-Dame":{"count":69},"École primaire privée Saint-Joseph":{"count":132},"École primaire privée Sainte-Marie":{"count":63},"École élémentaire Jules Ferry":{"count":52},"Școala Generală":{"count":51},"Școală":{"count":53},"Вечерняя школа":{"count":53},"Гимназия №1":{"count":96},"ДЮСШ":{"count":63},"Средняя школа №1":{"count":80},"Средняя школа №2":{"count":86},"Средняя школа №3":{"count":58},"Школа № 1":{"count":130},"Школа № 2":{"count":117},"Школа № 3":{"count":80},"Школа № 4":{"count":77},"Школа № 5":{"count":55},"Школа №1":{"count":576},"Школа №10":{"count":167},"Школа №11":{"count":148},"Школа №12":{"count":136},"Школа №13":{"count":129},"Школа №14":{"count":123},"Школа №15":{"count":129},"Школа №16":{"count":99},"Школа №17":{"count":117},"Школа №18":{"count":111},"Школа №19":{"count":98},"Школа №2":{"count":509},"Школа №20":{"count":100},"Школа №21":{"count":72},"Школа №22":{"count":72},"Школа №23":{"count":75},"Школа №24":{"count":78},"Школа №25":{"count":57},"Школа №26":{"count":64},"Школа №27":{"count":58},"Школа №28":{"count":53},"Школа №3":{"count":393},"Школа №31":{"count":55},"Школа №35":{"count":54},"Школа №4":{"count":281},"Школа №5":{"count":275},"Школа №6":{"count":217},"Школа №7":{"count":215},"Школа №8":{"count":188},"Школа №9":{"count":183},"مدرسة":{"count":92},"مدرسه":{"count":500},"市立南中学校":{"count":53},"市立南小学校":{"count":56},"市立東中学校":{"count":54}},"social_facility":{"Safe Haven":{"count":92},"Детский дом":{"count":70},"Социальный участковый":{"count":195}},"theatre":{"Amfiteatr":{"count":97},"Amphitheater":{"count":110},"Amphitheatre":{"count":109},"Anfiteatro":{"count":94},"Freilichtbühne":{"count":78},"Teatro Comunale":{"count":56},"Teatro Municipal":{"count":94}},"veterinary":{"Clinica Veterinaria":{"count":75},"Veterinaria":{"count":153}}};
18595 var leisure = {"fitness_centre":{"Anytime Fitness":{"count":143},"Gold's Gym":{"count":61},"LA Fitness":{"count":126},"Planet Fitness":{"count":106},"Snap Fitness":{"count":67}},"playground":{"Çocuk Parkı":{"count":60},"놀이터":{"count":292}},"sports_centre":{"Anytime Fitness":{"count":152},"Complejo Municipal de Deportes":{"count":88},"Complexe Sportif":{"count":51},"Curves":{"count":91},"Fitness First":{"count":70},"Gold's Gym":{"count":82},"Kieser Training":{"count":90},"LA Fitness":{"count":72},"Life Time Fitness":{"count":76},"McFit":{"count":60},"Mrs. Sporty":{"count":76},"Orlik":{"count":82},"Pabellón Municipal de Deportes":{"count":109},"Palestra Comunale":{"count":81},"Planet Fitness":{"count":106},"Polideportivo":{"count":248},"Salle Omnisport":{"count":57},"Schützenhaus":{"count":79},"Snap Fitness":{"count":51},"Virgin Active":{"count":69},"YMCA":{"count":174},"ДЮСШ":{"count":82},"Ледовый дворец":{"count":54},"体育館":{"count":80}},"swimming_pool":{"Schwimmerbecken":{"count":57},"Yüzme Havuzu":{"count":51},"プール":{"count":56},"游泳池":{"count":55}}};
18596 var man_made = {"windmill":{"De Hoop":{"count":57}}};
18597 var shop = {"alcohol":{"Alko":{"count":170},"BC Liquor Store":{"count":66},"BWS":{"count":157},"Bargain Booze":{"count":140},"Beer Store":{"count":66},"Botilleria":{"count":121},"Dan Murphy's":{"count":61},"Gall & Gall":{"count":511},"LCBO":{"count":430},"Liquor Depot":{"count":53},"Liquor Store":{"count":72},"Liquorland":{"count":112},"Mitra":{"count":60},"Nicolas":{"count":253},"SAQ":{"count":169},"Systembolaget":{"count":271},"The Beer Store":{"count":231},"Vinmonopolet":{"count":66},"Алкомаркет":{"count":67},"Ароматный мир":{"count":196},"Бристоль":{"count":329},"Градус":{"count":52},"Живое пиво":{"count":182},"Красное & Белое":{"count":989},"Кристалл":{"count":56},"Норман":{"count":146},"Отдохни":{"count":75},"Пиво":{"count":73},"Разливное пиво":{"count":143}},"baby_goods":{"Aubert":{"count":56},"Babies R Us":{"count":80},"BabyOne":{"count":52},"西松屋":{"count":53}},"bakery":{"AILI":{"count":53},"Anker":{"count":85},"Awiteks":{"count":53},"Backshop":{"count":57},"Backwerk":{"count":161},"Baguette":{"count":72},"Bakers Delight":{"count":75},"Bakker Bart":{"count":97},"Banette":{"count":111},"Bäckerei Fuchs":{"count":62},"Bäckerei Grimminger":{"count":51},"Bäckerei Müller":{"count":68},"Bäckerei Schmidt":{"count":103},"Bäckerei Schneider":{"count":52},"Cooplands":{"count":63},"Dat Backhus":{"count":81},"Der Beck":{"count":114},"Der Mann":{"count":53},"Ditsch":{"count":70},"Dunkin' Donuts":{"count":55,"tags":{"cuisine":"donut"}},"Fornetti":{"count":113},"Goeken backen":{"count":53},"Goldilocks":{"count":124},"Greggs":{"count":613},"Hofpfisterei":{"count":134},"Ihle":{"count":108},"Julie's Bakeshop":{"count":57},"K&U":{"count":117},"K&U Bäckerei":{"count":54},"Kamps":{"count":268},"La Mie Câline":{"count":56},"Le Crobag":{"count":54},"Le Fournil":{"count":57},"Lila Bäcker":{"count":107},"Lipóti Pékség":{"count":54},"Marie Blachère":{"count":89},"Mlinar":{"count":80},"Musmanni":{"count":81},"Oebel":{"count":65},"Panaderia":{"count":615},"Paul":{"count":186},"Red Ribbon":{"count":72},"Schäfer's":{"count":146},"Sehne":{"count":91},"Stadtbäckerei":{"count":60},"Steinecke":{"count":268},"Sternenbäck":{"count":89},"Ströck":{"count":62},"Wiener Feinbäcker":{"count":55},"von Allwörden":{"count":65},"Булочная":{"count":71},"Горячий хлеб":{"count":54},"Каравай":{"count":56},"Кулиничи":{"count":121},"Кулиничі":{"count":59},"Свежий хлеб":{"count":68},"Хлеб":{"count":177},"مخبز":{"count":72},"مخبزة":{"count":55},"نان لواش":{"count":54},"نانوایی":{"count":665},"نانوایی بربری":{"count":140},"نانوایی سنگک":{"count":68},"نانوایی سنگکی":{"count":52},"نانوایی لواش":{"count":63}},"beauty":{"Marionnaud":{"count":54},"Sally Beauty Supply":{"count":151},"Yves Rocher":{"count":654}},"bed":{"Dänisches Bettenlager":{"count":157},"Matratzen Concord":{"count":361},"Mattress Firm":{"count":173},"Sleepy's":{"count":52}},"beverages":{"50嵐":{"count":101},"Dursty":{"count":77},"Edeka Getränkemarkt":{"count":69},"Fristo":{"count":88},"Getränke Hoffmann":{"count":187},"Getränkeland":{"count":81},"Getränkemarkt":{"count":110},"Orterer Getränkemarkt":{"count":64},"REWE Getränkemarkt":{"count":256},"Trinkgut":{"count":112},"茶湯會":{"count":56}},"bicycle":{"Giant":{"count":52},"Halfords":{"count":158},"Веломарка":{"count":51},"サイクルベースあさひ":{"count":87}},"bookmaker":{"Betfred":{"count":320},"Coral":{"count":466},"Ladbrokes":{"count":629},"Paddy Power":{"count":127},"William Hill":{"count":634},"ΟΠΑΠ":{"count":102}},"boutique":{"Boutique":{"count":84}},"butcher":{"Boucherie Charcuterie":{"count":51},"Carnicería":{"count":78},"Fleischerei Richter":{"count":51},"Húsbolt":{"count":52},"Macelleria":{"count":84},"Vinzenzmurr":{"count":55},"Ариант":{"count":84},"Великолукский мясокомбинат":{"count":173},"Мясная лавка":{"count":226},"Мясницкий ряд":{"count":64},"Мясной":{"count":53},"Мясо":{"count":156},"Наша Ряба":{"count":60},"Свежее мясо":{"count":111}},"car":{"Audi":{"count":191},"BMW":{"count":216},"Chevrolet":{"count":259},"Citroen":{"count":445},"Dacia":{"count":56},"Fiat":{"count":167},"Ford":{"count":446},"Honda":{"count":348},"Hyundai":{"count":421},"Isuzu":{"count":66},"Kia":{"count":456},"Land Rover":{"count":54},"Lexus":{"count":76},"Mazda":{"count":193},"Mercedes-Benz":{"count":447},"Mitsubishi":{"count":176},"Mitsubishi Motors":{"count":60},"NISSAN":{"count":51},"Nissan":{"count":424},"Opel":{"count":218},"Peugeot":{"count":527},"Porsche":{"count":97},"Renault":{"count":701},"Seat":{"count":90},"Skoda":{"count":143},"Subaru":{"count":118},"Suzuki":{"count":178},"Toyota":{"count":597},"Volkswagen":{"count":371},"Volvo":{"count":180}},"car_parts":{"Advance Auto Parts":{"count":306},"AutoZone":{"count":759},"Brezan":{"count":95},"Halfords":{"count":95},"NAPA Auto Parts":{"count":250},"Napa Auto Parts":{"count":61},"O'Reilly Auto Parts":{"count":374},"Repco":{"count":77},"Tokić":{"count":61},"repuestos automotrices":{"count":56},"Автозапчастини":{"count":61},"Автомир":{"count":53},"イエローハット":{"count":80},"オートバックス":{"count":91},"タイヤ館":{"count":83}},"car_repair":{"A.T.U":{"count":457},"Advance Auto Parts":{"count":290},"Borracharia":{"count":56},"Bosch Car Service":{"count":65},"Carglass":{"count":234},"Citroen":{"count":108},"Euromaster":{"count":142},"Feu Vert":{"count":178},"Firestone":{"count":224},"Firestone Complete Auto Care":{"count":73},"Ford":{"count":61},"Garage Renault":{"count":84},"Gomeria":{"count":153},"Gomería":{"count":107},"Goodyear":{"count":97},"Grease Monkey":{"count":57},"Halfords":{"count":56},"Jiffy Lube":{"count":464},"Kwik Fit":{"count":249},"Lubricentro":{"count":83},"Meineke":{"count":52},"Mekonomen":{"count":59},"Midas":{"count":462},"Mr. Lube":{"count":56},"NAPA Auto Parts":{"count":82},"Norauto":{"count":257},"O'Reilly Auto Parts":{"count":227},"Pep Boys":{"count":79},"Peugeot":{"count":152},"Pit Stop":{"count":84},"Point S":{"count":59},"Renault":{"count":294},"Roady":{"count":82},"Sears Auto Center":{"count":59},"Speedy":{"count":192},"Stacja Kontroli Pojazdów":{"count":70},"Taller":{"count":63},"Toyota":{"count":63},"Valvoline":{"count":52},"Valvoline Instant Oil Change":{"count":92},"Wulkanizacja":{"count":84},"ÖAMTC":{"count":52},"Автомастерская":{"count":93},"Авторемонт":{"count":57},"Автосервис":{"count":799},"Автосервис+шиномонтаж":{"count":66},"Вулканизация":{"count":72},"Замена масла":{"count":98},"СТО":{"count":1058},"Шиномонтаж":{"count":3591},"шиномонтаж":{"count":173}},"carpet":{"Carpet Right":{"count":111},"Carpetright":{"count":53}},"charity":{"Age UK":{"count":116},"Barnardo's":{"count":56},"British Heart Foundation":{"count":189},"Cancer Research UK":{"count":129},"Goodwill":{"count":120},"Oxfam":{"count":216},"Salvation Army":{"count":63},"Scope":{"count":74},"Sue Ryder":{"count":83}},"chemist":{"7 Дней":{"count":55},"Bipa":{"count":485},"Budnikowsky":{"count":114},"CVS":{"count":58},"Etos":{"count":486},"Kruidvat":{"count":1169},"Matas":{"count":74},"Müller":{"count":350},"Rossmann":{"count":2516},"Schlecker":{"count":51},"Teta":{"count":120},"Trekpleister":{"count":185},"Walgreens":{"count":142},"Watsons":{"count":123},"dm":{"count":1877},"Бытовая химия":{"count":73},"Магнит Косметик":{"count":233},"Мила":{"count":70},"Остров чистоты":{"count":110},"Рубль Бум":{"count":68},"Улыбка радуги":{"count":110},"スギ薬局":{"count":51},"丁丁藥局":{"count":72},"屈臣氏":{"count":134},"康是美":{"count":81}},"clothes":{"AOKI":{"count":119},"AWG":{"count":95},"Ackermans":{"count":98},"Adidas":{"count":224},"Adler":{"count":83},"American Apparel":{"count":89},"American Eagle Outfitters":{"count":93},"Anthropologie":{"count":55},"Ardene":{"count":55},"Armand Thiery":{"count":89},"Banana Republic":{"count":120},"Benetton":{"count":190},"Bershka":{"count":166},"Bonita":{"count":315},"Bonobo":{"count":59},"Brooks Brothers":{"count":55},"Burberry":{"count":63},"Burlington Coat Factory":{"count":104},"Burton":{"count":94},"C&A":{"count":860},"Cache Cache":{"count":59},"Calvin Klein":{"count":78},"Calzedonia":{"count":264},"Camaïeu":{"count":167},"Caroll":{"count":75},"Carter's":{"count":64},"Cecil":{"count":119},"Celio":{"count":206},"Charles Vögele":{"count":133},"Chico's":{"count":96},"Cropp":{"count":68},"Cubus":{"count":65},"Desigual":{"count":175},"Devred":{"count":59},"Didi":{"count":72},"Diesel":{"count":77},"Dorothy Perkins":{"count":85},"Dress Barn":{"count":135},"Dressmann":{"count":67},"Eddie Bauer":{"count":54},"Edgars":{"count":117},"Engbers":{"count":64},"Ernsting's family":{"count":720},"Esprit":{"count":404},"Etam":{"count":121},"Express":{"count":56},"Fat Face":{"count":82},"Forever 21":{"count":124},"Gant":{"count":78},"Gap":{"count":258},"Gerry Weber":{"count":220},"Gina Laura":{"count":80},"Goodwill":{"count":65},"Guess":{"count":146},"Gymboree":{"count":60},"Gémo":{"count":99},"H&M":{"count":1467},"Hallhuber":{"count":63},"House":{"count":67},"Hugo Boss":{"count":109},"Humana":{"count":83},"Hunkemöller":{"count":224},"Intimissimi":{"count":173},"JBC":{"count":54},"Jack & Jones":{"count":174},"Jack Wolfskin":{"count":68},"Jeans Fritz":{"count":110},"Jennyfer":{"count":81},"Jet":{"count":68},"Jigsaw":{"count":51},"Jules":{"count":120},"Justice":{"count":81},"KappAhl":{"count":68},"KiK":{"count":1862},"Kiabi":{"count":276},"La Halle":{"count":148},"Lacoste":{"count":193},"Lane Bryant":{"count":86},"Levi's":{"count":197},"Lindex":{"count":120},"Loft":{"count":62},"Mango":{"count":339},"Marc O'Polo":{"count":82},"Mark's":{"count":76},"Marks & Spencer":{"count":53},"Marshalls":{"count":218},"Massimo Dutti":{"count":109},"Matalan":{"count":144},"Maurices":{"count":70},"Max Mara":{"count":55},"Men's Wearhouse":{"count":128},"Mexx":{"count":68},"Michael Kors":{"count":55},"Mim":{"count":57},"Monsoon":{"count":75},"Mr Price":{"count":99},"NKD":{"count":783},"New Look":{"count":280},"New Yorker":{"count":350},"NewYorker":{"count":54},"Next":{"count":313},"Nike":{"count":122},"Nordstrom Rack":{"count":57},"OVS":{"count":92},"Okaïdi":{"count":63},"Old Navy":{"count":361},"Only":{"count":94},"Orchestra":{"count":117},"Original Marines":{"count":60},"Orsay":{"count":168},"Outfit":{"count":51},"Outlet":{"count":63},"Palmers":{"count":78},"Peacocks":{"count":178},"Peek & Cloppenburg":{"count":69},"Pep":{"count":139},"Pepco":{"count":153},"Petit Bateau":{"count":67},"Pimkie":{"count":163},"Plato's Closet":{"count":53},"Primark":{"count":177},"Promod":{"count":195},"Pull & Bear":{"count":63},"Puma":{"count":65},"Reitmans":{"count":71},"Reserved":{"count":150},"River Island":{"count":125},"Ross":{"count":363},"Sela":{"count":58},"Sergent Major":{"count":77},"Shoeby":{"count":109},"Sisley":{"count":82},"Springfield":{"count":83},"Stefanel":{"count":63},"Steps":{"count":56},"Stradivarius":{"count":103},"Street One":{"count":153},"Superdry":{"count":82},"TJ Maxx":{"count":200},"TK Maxx":{"count":209},"Takko":{"count":843},"Talbots":{"count":54},"Tally Weijl":{"count":151},"Tati":{"count":64},"Terranova":{"count":63},"Tesha":{"count":76},"Tezenis":{"count":98},"The Children's Place":{"count":71},"The North Face":{"count":56},"The Sting":{"count":53},"Timberland":{"count":87},"Toko Pakaian":{"count":72},"Tom Tailor":{"count":120},"Tommy Hilfiger":{"count":206},"Topshop":{"count":62},"Triumph":{"count":132},"Truworths":{"count":72},"Ulla Popken":{"count":117},"Uniqlo":{"count":63},"United Colors of Benetton":{"count":210},"Urban Outfitters":{"count":130},"Vero Moda":{"count":222},"Victoria's Secret":{"count":143},"Vögele":{"count":191},"WE":{"count":68},"Wibra":{"count":99},"Winners":{"count":112},"Woolworths":{"count":119},"Yamamay":{"count":65},"Zara":{"count":540},"Zeeman":{"count":379},"mister*lady":{"count":59},"s.Oliver":{"count":103},"Детская одежда":{"count":59},"Женская одежда":{"count":65},"Липненски":{"count":81},"Московская ярмарка":{"count":51},"Одежда":{"count":163},"Смешные цены":{"count":86},"Спецодежда":{"count":85},"しまむら":{"count":213},"ユニクロ":{"count":201},"ワークマン":{"count":65},"洋服の青山":{"count":242},"西松屋":{"count":113}},"coffee":{"Café Amazon":{"count":212},"Coffee Shop":{"count":71},"Nespresso":{"count":74},"Starbucks":{"count":264,"tags":{"cuisine":"coffee_shop"}},"Tchibo":{"count":197}},"computer":{"Apple Store":{"count":75},"DNS":{"count":234},"PC World":{"count":59},"ДНС":{"count":55}},"confectionery":{"Fagyizó":{"count":58},"Hussel":{"count":78},"Leonidas":{"count":84},"T. SN":{"count":77},"Thorntons":{"count":66}},"convenience":{"711":{"count":64},"777":{"count":58},"24 часа":{"count":85},"7-Eleven":{"count":11418},"8 à Huit":{"count":82},"99 Speedmart":{"count":85},"ABC":{"count":716},"AMPM":{"count":125},"Aibė":{"count":112},"Alepa":{"count":60},"Alfamart":{"count":427},"Alimentara":{"count":63},"Almacen":{"count":405},"Almacén":{"count":94},"Aral":{"count":93},"BP":{"count":273},"BP Shop":{"count":70},"Baqala":{"count":181},"Best One":{"count":57},"Best-One":{"count":63},"Biedronka":{"count":98},"Bodega":{"count":83},"Bonjour":{"count":71},"Boutique":{"count":341},"CBA":{"count":299},"COOP":{"count":470},"COOP Jednota":{"count":381},"CU":{"count":324},"Carrefour City":{"count":91},"Carrefour Express":{"count":255},"Casey's General Store":{"count":225},"Casino":{"count":91},"Casino Shop":{"count":56},"Centra":{"count":139},"Central Convenience Store":{"count":69},"Chevron":{"count":110},"Circle K":{"count":790},"Citgo":{"count":73},"Co-Op":{"count":54},"Co-op":{"count":161},"Coles Express":{"count":217},"Coop":{"count":492},"Coop Jednota":{"count":128},"Corner Store":{"count":109},"Costcutter":{"count":435},"Couche-Tard":{"count":139},"Cumberland Farms":{"count":109},"Daisy Mart":{"count":57},"Delikatesy":{"count":148},"Delikatesy Centrum":{"count":182},"Dollar General":{"count":646},"Dollar Tree":{"count":67},"Dépanneur":{"count":53},"Esso":{"count":143},"Express":{"count":53},"Extra":{"count":86},"Exxon":{"count":51},"Family Dollar":{"count":85},"FamilyMart":{"count":919},"Food Mart":{"count":512},"Four Square":{"count":99},"Franprix":{"count":96},"Fresh":{"count":67},"Freshmarket":{"count":224},"GS25":{"count":343},"Groszek":{"count":254},"Hasty Market":{"count":87},"Holiday":{"count":67},"Hruška":{"count":89},"Indomaret":{"count":483},"Jednota":{"count":66},"Joker":{"count":56},"K-Market":{"count":104},"Kangaroo":{"count":54},"Kangaroo Express":{"count":51},"Kiosco":{"count":74},"Kiosk":{"count":557},"Kisbolt":{"count":94},"Konzum":{"count":229},"Kum & Go":{"count":127},"Kwik Trip":{"count":134},"LAWSON":{"count":311},"Lewiatan":{"count":565},"Lifestyle Express":{"count":114},"Londis":{"count":505},"M&S Simply Food":{"count":72},"Mac's":{"count":295},"Mace":{"count":166},"Magazin":{"count":81},"Magazin Mixt":{"count":139},"Magazin Non-Stop":{"count":62},"Magazin mixt":{"count":57},"Marathon":{"count":59},"Maxikiosco":{"count":86},"Małpka Express":{"count":71},"McColl's":{"count":289},"Mercator":{"count":122},"Migrolino":{"count":63},"Mini ABC":{"count":77},"Mini Market":{"count":1312},"Mini Market Non-Stop":{"count":134},"Mini Mart":{"count":78},"Mini Stop":{"count":466},"Minimarket":{"count":255},"Minimercado":{"count":77},"Mlin i pekare":{"count":63},"Mobil":{"count":82},"Nasz Sklep":{"count":92},"Nisa":{"count":70},"Nisa Local":{"count":164},"OK":{"count":107},"OK-Mart":{"count":51},"OK便利商店":{"count":96},"OK便利店 Circle K":{"count":92},"Odido":{"count":148},"On The Run":{"count":53},"On the Run":{"count":111},"One Stop":{"count":294},"Oxxo":{"count":2261},"Parduotuvė":{"count":102},"Petit Casino":{"count":297},"Plaid Pantry":{"count":69},"Potraviny":{"count":438},"Prehrana":{"count":88},"Premier":{"count":321},"Proxi":{"count":249},"Proxy":{"count":53},"Pulperia":{"count":56},"Pulpería":{"count":51},"QuikTrip":{"count":161},"Rite Aid":{"count":72},"Royal Farms":{"count":90},"Sainsbury's Local":{"count":208},"Sale":{"count":89},"Sari-sari Store":{"count":82},"Select":{"count":133},"Sheetz":{"count":137},"Shell":{"count":479},"Shell Select":{"count":71},"Shop & Go":{"count":80},"Siwa":{"count":157},"Sklep spożywczy":{"count":151},"Smíšené zboží":{"count":57},"Spar":{"count":1472},"Speedway":{"count":108},"Społem":{"count":199},"Spätkauf":{"count":60},"Statoil":{"count":62},"Stewart's":{"count":255},"Stores":{"count":70},"Stripes":{"count":63},"Studenac":{"count":113},"Sunkus":{"count":51},"Sunoco":{"count":65},"Słoneczko":{"count":61},"TESCO Lotus Express":{"count":55},"Tchibo":{"count":75},"Tesco":{"count":54},"Tesco Express":{"count":661},"Tesco Lotus Express":{"count":107},"The Co-operative Food":{"count":341},"Tom Market 89":{"count":232},"Total":{"count":172},"United Dairy Farmers":{"count":55},"Utile":{"count":63},"Valero":{"count":71},"Vegyesbolt":{"count":391},"Večerka":{"count":131},"Vival":{"count":381},"Volg":{"count":149},"Wawa":{"count":279},"Weltladen":{"count":64},"Woolworths Petrol":{"count":97},"abc":{"count":374},"ampm":{"count":152},"best-one":{"count":52},"odido":{"count":77},"Élelmiszer":{"count":59},"Élelmiszerbolt":{"count":65},"Żabka":{"count":1656},"Žabka":{"count":61},"АТБ":{"count":56},"Августина":{"count":52},"Авоська":{"count":115},"Агрокомплекс":{"count":79},"Альянс":{"count":51},"Апельсин":{"count":72},"Ассорти":{"count":118},"Белорусские продукты":{"count":58},"Берёзка":{"count":193},"Везунчик":{"count":66},"Верный":{"count":61},"Весна":{"count":101},"Ветеран":{"count":56},"Визит":{"count":99},"Виктория":{"count":164},"ВкусВилл":{"count":131},"Гастроном":{"count":383},"Гермес":{"count":68},"Гроздь":{"count":52},"Гурман":{"count":92},"Дикси":{"count":270},"Домашний":{"count":77},"Евроопт":{"count":152},"Елена":{"count":68},"Ермолино":{"count":51},"КазМунайГаз":{"count":117},"Калинка":{"count":61},"Каравай":{"count":52},"Квартал":{"count":57},"Кировский":{"count":86},"Колобок":{"count":51},"Колосок":{"count":58},"Копеечка":{"count":99},"Копейка":{"count":65},"Корзинка":{"count":54},"Крамниця":{"count":64},"Кристалл":{"count":57},"Кулинария":{"count":134},"Купец":{"count":64},"Ласточка":{"count":51},"Лидер":{"count":60},"Любимый":{"count":84},"Люкс":{"count":59},"Магазин при АЗС":{"count":54},"Магнит":{"count":1991},"Магнолия":{"count":88},"Мария-Ра":{"count":197},"Маяк":{"count":76},"Меркурий":{"count":77},"Мечта":{"count":103},"Минимаркет":{"count":424},"Мираж":{"count":56},"Монетка":{"count":165},"Надежда":{"count":115},"Ника":{"count":57},"Оазис":{"count":57},"Олимп":{"count":51},"Перекресток":{"count":157},"Подсолнух":{"count":69},"Престиж":{"count":58},"Продукти":{"count":1446},"Продуктовый":{"count":307},"Продуктовый магазин":{"count":803},"Продукты":{"count":8416},"Продукты 24":{"count":65},"Пятёрочка":{"count":1324},"Радуга":{"count":165},"Родны кут":{"count":90},"Ромашка":{"count":83},"Русь":{"count":61},"Светлана":{"count":96},"Сказка":{"count":62},"Смак":{"count":151},"Солнечный":{"count":54},"Солнышко":{"count":54},"Татьяна":{"count":68},"Теремок":{"count":105},"Тройка":{"count":62},"У Палыча":{"count":69},"Универсам":{"count":153},"Фортуна":{"count":97},"Хороший":{"count":55},"Центральный":{"count":73},"Чайка":{"count":57},"Шанс":{"count":60},"Эконом":{"count":72},"Юбилейный":{"count":56},"Юлия":{"count":58},"продукты":{"count":157},"მარკეტი":{"count":134},"მარკეტი (Market)":{"count":71},"サンクス":{"count":970,"tags":{"name:en":"sunkus"}},"サークルK":{"count":1109,"tags":{"name:en":"Circle K"}},"スリーエフ":{"count":228},"セイコーマート":{"count":449},"セブンイレブン":{"count":7859,"tags":{"name:en":"7-Eleven"}},"セブンイレブン(Seven-Eleven)":{"count":332},"セーブオン":{"count":71},"デイリーヤマザキ":{"count":421},"ファミリーマート":{"count":4457,"tags":{"name:en":"FamilyMart"}},"ポプラ":{"count":101},"ミニストップ":{"count":773,"tags":{"name:en":"MINISTOP"}},"ヤマザキショップ":{"count":106},"ローソン":{"count":4247,"tags":{"name:en":"LAWSON"}},"ローソンストア100":{"count":272},"全家":{"count":482},"全家便利商店":{"count":833},"萊爾富":{"count":405},"세븐일레븐":{"count":157}},"copyshop":{"FedEx Office":{"count":53},"FedEx Office Print and Ship Center":{"count":170}},"cosmetics":{"Douglas":{"count":58},"Lush":{"count":80},"Marionnaud":{"count":55},"Sephora":{"count":184},"The Body Shop":{"count":95},"Yves Rocher":{"count":111},"Л'Этуаль":{"count":111},"Магнит Косметик":{"count":116},"Магнит косметик":{"count":63},"Магнит-Косметик":{"count":55},"Мила":{"count":68},"Подружка":{"count":51}},"craft":{"Hobby Lobby":{"count":96},"Michaels":{"count":222}},"deli":{"ほっともっと":{"count":58}},"department_store":{"Argos":{"count":90},"Bed Bath & Beyond":{"count":72},"Big Lots":{"count":142},"Big W":{"count":120},"Canadian Tire":{"count":176},"Coppel":{"count":55},"Debenhams":{"count":118},"Dillard's":{"count":86},"Dollar General":{"count":62},"Dollar Tree":{"count":64},"El Corte Inglés":{"count":61},"Family Dollar":{"count":76},"Fred Meyer":{"count":51},"Galeria Kaufhof":{"count":60},"HEMA":{"count":248},"Harvey Norman":{"count":62},"JCPenney":{"count":365},"Karstadt":{"count":66},"Kmart":{"count":390},"Kohl's":{"count":371},"Lojas Americanas":{"count":63},"Macy's":{"count":292},"Marks & Spencer":{"count":136},"Marshalls":{"count":58},"Myer":{"count":51},"Nordstrom":{"count":54},"Sam's Club":{"count":103},"Sears":{"count":462},"Shopko":{"count":65},"Target":{"count":1104},"The Warehouse":{"count":68},"Walmart":{"count":847},"Walmart Supercenter":{"count":234},"Woolworth":{"count":153},"Магнит":{"count":88},"Универмаг":{"count":170}},"doityourself":{"Ace Hardware":{"count":300},"B&Q":{"count":229},"Bauhaus":{"count":223},"Biltema":{"count":64},"Brico":{"count":126},"Bricomarché":{"count":425},"Bricorama":{"count":117},"Bunnings Warehouse":{"count":210},"Canadian Tire":{"count":138},"Castorama":{"count":168},"Easy":{"count":53},"Gamma":{"count":133},"Globus Baumarkt":{"count":52},"Hagebaumarkt":{"count":132},"Hellweg":{"count":70},"Home Depot":{"count":1345},"Home Hardware":{"count":172},"Homebase":{"count":205},"Hornbach":{"count":134},"Hubo":{"count":107},"Karwei":{"count":77},"Lagerhaus":{"count":116},"Leroy Merlin":{"count":285},"Lowe's":{"count":1236},"Lowes":{"count":95},"Menards":{"count":132},"Mr Bricolage":{"count":112},"Mr.Bricolage":{"count":139},"OBI":{"count":501},"Point P":{"count":125},"Praktiker":{"count":54},"Praxis":{"count":61},"Rona":{"count":77},"Screwfix":{"count":80},"Sonderpreis Baumarkt":{"count":68},"Tekzen":{"count":112},"Toom Baumarkt":{"count":155},"Weldom":{"count":110},"Wickes":{"count":159},"Леруа Мерлен":{"count":54},"Мастер":{"count":59},"Сантехника":{"count":51},"Строитель":{"count":67},"Стройматериалы":{"count":506},"Хозтовары":{"count":137},"カインズホーム":{"count":51},"コメリ":{"count":137},"コーナン":{"count":77}},"dry_cleaning":{"Cleaners":{"count":103},"Pressing":{"count":58},"Диана":{"count":88},"Химчистка":{"count":73},"ホワイト急便":{"count":136}},"electronics":{"Apple Store":{"count":63},"BCC":{"count":54},"Batteries Plus Bulbs":{"count":74},"Bell":{"count":73},"Best Buy":{"count":706},"Boulanger":{"count":71},"Currys":{"count":109},"Currys PC World":{"count":70},"DNS":{"count":111},"Darty":{"count":168},"Elektra":{"count":64},"Elgiganten":{"count":67},"Euronics":{"count":247},"Expert":{"count":224},"Hartlauer":{"count":64},"Interdiscount":{"count":57},"La Curacao":{"count":69},"Maplin":{"count":114},"Media Expert":{"count":163},"Media Markt":{"count":422},"Musimundo":{"count":53},"Neonet":{"count":97},"RTV Euro AGD":{"count":68},"Radio Shack":{"count":485},"Rogers":{"count":61},"Samsung":{"count":164},"Saturn":{"count":155},"Sony":{"count":51},"The Source":{"count":91},"Unieuro":{"count":66},"М.Видео":{"count":121},"Фокстрот":{"count":76},"Эксперт":{"count":70},"Эльдорадо":{"count":313},"エディオン":{"count":74},"ケーズデンキ":{"count":136},"コジマ":{"count":53},"ヤマダ電機":{"count":162},"全國電子":{"count":72},"燦坤3C":{"count":52}},"erotic":{"Orion":{"count":85}},"fabric":{"Ткани":{"count":121}},"farm":{"Hofladen":{"count":63}},"florist":{"Blume 2000":{"count":94},"Blumen Risse":{"count":69},"Fleuriste":{"count":54},"Interflora":{"count":78},"Monceau Fleurs":{"count":69},"Virágbolt":{"count":64},"Квіти":{"count":86},"Цветочный магазин":{"count":57},"Цветы":{"count":1098}},"frame":{"rumah penduduk":{"count":316}},"funeral_directors":{"Funeraria":{"count":51},"The Co-operative Funeralcare":{"count":82},"Ритуальные услуги":{"count":133}},"furniture":{"Aaron's":{"count":57},"Black Red White":{"count":79},"Bodzio":{"count":61},"But":{"count":162},"Casa":{"count":62},"Conforama":{"count":174},"DFS":{"count":52},"Dänisches Bettenlager":{"count":464},"Fly":{"count":53},"Harveys":{"count":58},"IKEA":{"count":234},"JYSK":{"count":431},"Kwantum":{"count":54},"Leen Bakker":{"count":72},"Pier 1 Imports":{"count":95},"Roller":{"count":99},"The Brick":{"count":68},"Меблі":{"count":70},"ニトリ":{"count":93}},"garden_centre":{"Dehner":{"count":59},"Gamm Vert":{"count":210},"Jardiland":{"count":124},"Point Vert":{"count":68},"Welkoop":{"count":97},"Семена":{"count":53}},"gift":{"Card Factory":{"count":116},"Hallmark":{"count":163},"Подарки":{"count":56}},"greengrocer":{"Frutería":{"count":60},"Овощи и фрукты":{"count":71}},"hairdresser":{"Barbershop":{"count":51},"Berber":{"count":71},"Cost Cutters":{"count":69},"Fantastic Sams":{"count":53},"Figaro":{"count":79},"First Choice Haircutters":{"count":51},"Franck Provost":{"count":136},"Frizerie":{"count":59},"Great Clips":{"count":578},"Haarmonie":{"count":79},"Haarscharf":{"count":59},"Hair Cuttery":{"count":121},"Hairkiller":{"count":73},"Jean Louis David":{"count":90},"Jean-Louis David":{"count":59},"Klier":{"count":239},"Klipp":{"count":76},"Le Salon":{"count":55},"Marco Aldany":{"count":55},"Peluquería":{"count":165},"Salon":{"count":57},"Salon fryzjerski":{"count":52},"Sport Clips":{"count":114},"Super Cuts":{"count":55},"Supercuts":{"count":359},"Tchip":{"count":62},"The Barber Shop":{"count":130},"Toni & Guy":{"count":77},"Top Hair":{"count":74},"Виктория":{"count":53},"Елена":{"count":53},"Локон":{"count":67},"Парикмахерская":{"count":798},"Перукарня":{"count":119},"Салон красоты":{"count":58},"Стиль":{"count":94},"Шарм":{"count":79},"حلاق":{"count":65}},"hardware":{"1000 мелочей":{"count":125},"Ferretería":{"count":295},"Harbor Freight Tools":{"count":57},"Home Hardware":{"count":94},"Lowe's":{"count":74},"Quincaillerie":{"count":105},"True Value":{"count":52},"Würth":{"count":51},"Промтовары":{"count":67},"Сантехника":{"count":87},"Стройматериалы":{"count":142},"Товары для дома":{"count":69},"Хозтовары":{"count":477}},"hearing_aids":{"Amplifon":{"count":124},"Geers":{"count":66},"Kind Hörgeräte":{"count":74},"amplifon":{"count":52}},"hifi":{"Bang & Olufsen":{"count":51}},"houseware":{"Blokker":{"count":264},"Marskramer":{"count":72},"Xenos":{"count":119}},"ice_cream":{"Мороженое":{"count":51}},"interior_decoration":{"Casa":{"count":65},"Depot":{"count":97}},"jewelry":{"585":{"count":94},"Apart":{"count":53},"Bijou Brigitte":{"count":172},"Christ":{"count":116},"Claire's":{"count":99},"Ernest Jones":{"count":53},"H Samuel":{"count":55},"James Avery Jewelry":{"count":99},"Julien d'Orcel":{"count":123},"Kay Jewelers":{"count":78},"Pandora":{"count":280},"Swarovski":{"count":240},"Адамас":{"count":60},"Золото":{"count":51}},"kiosk":{"Aral":{"count":76},"Edicola":{"count":94},"Esso":{"count":51},"KIOS":{"count":288},"Kiosco":{"count":203},"Kiosk":{"count":869},"Kiosko":{"count":62},"Kiosque":{"count":68},"Kolporter":{"count":88},"Lietuvos spauda":{"count":62},"Narvesen":{"count":188},"Pressbyrån":{"count":117},"Pulpería":{"count":61},"R-Kioski":{"count":352},"Relay":{"count":61},"Ruch":{"count":187},"Shell":{"count":122},"Tabak Trafik":{"count":83},"Tisak":{"count":245},"Trafik":{"count":221},"Trafika":{"count":64},"Trinkhalle":{"count":98},"Warung":{"count":73},"Белсоюзпечать":{"count":59},"Киоск":{"count":143},"Мороженое":{"count":56},"Продукты":{"count":212},"Роспечать":{"count":233},"Союзпечать":{"count":94},"მარკეტი (Market)":{"count":94}},"kitchen":{"Cuisinella":{"count":60},"Home Utensils":{"count":65},"Kitchen":{"count":202},"kitchen":{"count":101}},"laundry":{"Launderette":{"count":51},"Lavandería":{"count":84},"コインランドリー":{"count":64}},"lottery":{"Loteria de la Provincia":{"count":63},"Lotería Nacional":{"count":221},"Lotería de la Provincia":{"count":349},"Lotto":{"count":192},"Lottózó":{"count":69},"ONCE":{"count":91}},"mall":{"Торговый центр":{"count":57}},"massage":{"Massage Envy":{"count":80}},"medical_supply":{"Pofam-Poznań":{"count":61}},"mobile_phone":{"3 Store":{"count":90},"AT&T":{"count":558},"Bell":{"count":140},"Bitė":{"count":66},"Boost Mobile":{"count":151},"Carphone Warehouse":{"count":357},"Claro":{"count":446},"Cricket":{"count":122},"Cricket Wireless":{"count":73},"Digicel":{"count":152},"EE":{"count":190},"MetroPCS":{"count":201},"Movistar":{"count":411},"O2":{"count":527},"Orange":{"count":730},"Personal":{"count":54},"Play":{"count":150},"Plus":{"count":122},"Rogers":{"count":52},"SFR":{"count":156},"Samsung":{"count":71},"Sprint":{"count":394},"T-Mobile":{"count":665},"TIM":{"count":67},"Telcel":{"count":52},"Tele2":{"count":186},"Telekom":{"count":148},"Telekom Shop":{"count":99},"Telenor":{"count":99},"Telus":{"count":69},"The Phone House":{"count":137},"Three":{"count":57},"Tim":{"count":51},"Télécentre":{"count":76},"Verizon":{"count":152},"Verizon Wireless":{"count":629},"Vodafone":{"count":1168},"Vodafone Shop":{"count":52},"Wind":{"count":156},"Yoigo":{"count":61},"au":{"count":136},"auショップ":{"count":340},"mobilcom debitel":{"count":63},"Алло":{"count":86},"Билайн":{"count":441},"Евросеть":{"count":1020},"Київстар":{"count":57},"МТС":{"count":1012},"Мегафон":{"count":687},"Связной":{"count":842},"Теле2":{"count":70},"ソフトバンクショップ":{"count":482},"ドコモショップ":{"count":426}},"money_lender":{"Money Mart":{"count":95}},"motorcycle":{"Harley Davidson":{"count":81},"Honda":{"count":238},"Suzuki":{"count":90},"Yamaha":{"count":235}},"music":{"HMV":{"count":81},"TSUTAYA":{"count":53}},"musical_instrument":{"Guitar Center":{"count":51}},"newsagent":{"Edicola":{"count":111},"Kolporter":{"count":56},"Maison de la Presse":{"count":132},"Relay":{"count":246},"Tabac Presse":{"count":82},"Trafika":{"count":60},"WHSmith":{"count":160},"Белсоюзпечать":{"count":52},"Витебскоблсоюзпечать":{"count":56},"Первая полоса":{"count":57},"Печать":{"count":74},"Роспечать":{"count":371},"Союзпечать":{"count":130}},"optician":{"Alain Afflelou":{"count":204},"Apollo":{"count":441},"Atol":{"count":124},"Boots Opticians":{"count":101},"Fielmann":{"count":477},"General Óptica":{"count":53},"Grand Optical":{"count":57},"Générale d'Optique":{"count":94},"Hakim Optical":{"count":73},"Hans Anders":{"count":105},"Krys":{"count":192},"Les Opticiens Mutualistes":{"count":103},"Optic 2000":{"count":281},"Optica":{"count":159},"Optical Center":{"count":125},"Pearle":{"count":199},"Pearle Vision":{"count":52},"Specsavers":{"count":384},"Sunglass Hut":{"count":61},"Synoptik":{"count":55},"Vision Express":{"count":183},"แว่นท็อปเจริญ":{"count":97},"メガネスーパー":{"count":62},"眼鏡市場":{"count":206}},"outdoor":{"Jack Wolfskin":{"count":51},"Mountain Warehouse":{"count":74},"REI":{"count":77},"Рыболов":{"count":70}},"paint":{"Benjamin Moore":{"count":58},"Comex":{"count":68},"Jotun":{"count":51},"National Paints":{"count":53},"Sherwin Williams":{"count":323},"Sherwin-Williams Paints":{"count":59}},"pawnbroker":{"Cash Converters":{"count":83},"Lombard":{"count":55},"Palawan Pawnshop":{"count":52}},"pet":{"Das Futterhaus":{"count":158},"Fressnapf":{"count":620},"Global Pet Foods":{"count":54},"Maxi Zoo":{"count":65},"Pet Valu":{"count":112},"PetSmart":{"count":491},"Petco":{"count":377},"Pets at Home":{"count":170},"Бетховен":{"count":60},"Зоотовары":{"count":79},"Четыре лапы":{"count":56}},"second_hand":{"Goodwill":{"count":235},"Value Village":{"count":53}},"shoes":{"Adidas":{"count":51},"Aldo":{"count":74},"Bata":{"count":281},"Besson Chaussures":{"count":124},"Brantano":{"count":132},"CCC":{"count":245},"Camper":{"count":51},"Chaussea":{"count":102},"Clarks":{"count":268},"Converse":{"count":58},"Crocs":{"count":64},"DSW":{"count":52},"Deichmann":{"count":1231},"Dosenbach":{"count":58},"Ecco":{"count":185},"Famous Footwear":{"count":178},"Foot Locker":{"count":240},"Geox":{"count":151},"Kari":{"count":66},"La Halle aux Chaussures":{"count":158},"Mephisto":{"count":57},"Minelli":{"count":55},"New Balance":{"count":52},"Payless":{"count":56},"Payless Shoe Source":{"count":316},"Payless ShoeSource":{"count":133},"Quick Schuh":{"count":116},"Rack Room Shoes":{"count":51},"Reno":{"count":233},"Rieker":{"count":83},"Salamander":{"count":103},"San Marina":{"count":54},"Scapino":{"count":67},"Shoe Carnival":{"count":66},"Shoe Zone":{"count":161},"Siemes Schuhcenter":{"count":69},"Skechers":{"count":83},"Tamaris":{"count":99},"Timberland":{"count":51},"vanHaren":{"count":98},"Éram":{"count":88},"Ремонт обуви":{"count":71},"ЦентрОбувь":{"count":76},"Юничел":{"count":73},"東京靴流通センター":{"count":81}},"sports":{"Adidas":{"count":132},"Aktiesport":{"count":61},"Big 5 Sporting Goods":{"count":93},"Decathlon":{"count":409},"Dick's Sporting Goods":{"count":222},"Hervis":{"count":66},"Intersport":{"count":737},"JD Sports":{"count":58},"Nike":{"count":95},"Sport 2000":{"count":209},"Sports Authority":{"count":108},"Sports Direct":{"count":217},"Stadium":{"count":53},"Спортмастер":{"count":208},"Спорттовары":{"count":68}},"stationery":{"Bureau Vallée":{"count":64},"Libro":{"count":73},"McPaper":{"count":158},"Office Depot":{"count":378},"Office Max":{"count":169},"Officeworks":{"count":73},"Pagro":{"count":64},"Paperchase":{"count":54},"Ryman":{"count":85},"Staples":{"count":671},"Канцтовары":{"count":140}},"supermarket":{"7-Eleven":{"count":60},"A&O":{"count":67},"A101":{"count":388},"AD Delhaize":{"count":80},"ADEG":{"count":85},"ALDI":{"count":6323},"Ahorramás":{"count":66},"Albert":{"count":245},"Albert Heijn":{"count":766},"Albertsons":{"count":316},"Aldi Nord":{"count":356},"Aldi Süd":{"count":916},"Alfamart":{"count":109},"Alimerka":{"count":96},"Alnatura":{"count":97},"Asda":{"count":474},"Atac":{"count":53},"Atacadão":{"count":80},"Auchan":{"count":229},"BM":{"count":52},"Biedronka":{"count":2348},"Big C":{"count":53},"Billa":{"count":1592},"Bim":{"count":678},"Biocoop":{"count":159},"Bodega Aurrera":{"count":264},"Budgens":{"count":77},"Bulk Barn":{"count":54},"Bunnpris":{"count":69},"CBA":{"count":236},"CONAD":{"count":67},"COOP":{"count":255},"COOP Jednota":{"count":177},"CRAI":{"count":66},"CU":{"count":64},"Caprabo":{"count":144},"Cargills Food City":{"count":79},"Carrefour":{"count":2544},"Carrefour City":{"count":349},"Carrefour Contact":{"count":270},"Carrefour Express":{"count":921},"Casino":{"count":337},"Centra":{"count":63},"Centre Commercial E. Leclerc":{"count":385},"Checkers":{"count":140},"Chedraui":{"count":80},"Co-Op":{"count":62},"Co-op":{"count":352},"Co-operative":{"count":51},"Coles":{"count":583},"Colmado":{"count":103},"Colruyt":{"count":212},"Combi":{"count":127},"Comercial Mexicana":{"count":59},"Conad":{"count":560},"Conad City":{"count":95},"Condis":{"count":126},"Consum":{"count":236},"Continente":{"count":111},"Coop":{"count":1665},"Coop Extra":{"count":88},"Coop Jednota":{"count":101},"Coop Konsum":{"count":96},"Costco":{"count":295},"Costcutter":{"count":93},"Coto":{"count":65},"Countdown":{"count":135},"Coviran":{"count":124},"Covirán":{"count":51},"Crai":{"count":119},"Cub Foods":{"count":57},"Dagli'Brugsen":{"count":135},"Deen":{"count":55},"Delhaize":{"count":228},"Delikatesy Centrum":{"count":209},"Denner":{"count":412},"Despar":{"count":209},"Despensa Familiar":{"count":81},"Dia":{"count":1329},"Dia %":{"count":181},"Dia Market":{"count":60},"Dino":{"count":298},"Dirk van den Broek":{"count":66},"Disco":{"count":74},"Diska":{"count":68},"Dollar General":{"count":106},"Dollar Tree":{"count":52},"Dunnes Stores":{"count":72},"E-Center":{"count":66},"E. Leclerc":{"count":186},"E. Leclerc Drive":{"count":97},"EKO":{"count":78},"EMTÉ":{"count":74},"Edeka":{"count":2231},"Ekom":{"count":64},"Ekono":{"count":68},"El Árbol":{"count":86},"Eroski":{"count":351},"Esselunga":{"count":106},"EuroSpin":{"count":81},"Eurospar":{"count":340},"Eurospin":{"count":328},"Extra":{"count":149},"Famiglia Cooperativa":{"count":89},"Famila":{"count":167},"Family Dollar":{"count":72},"Fareway":{"count":51},"Farmfoods":{"count":141},"Feneberg":{"count":64},"Food Basics":{"count":116},"Food Lion":{"count":425},"Foodland":{"count":192},"Foodworks":{"count":90},"Franprix":{"count":401},"Fred Meyer":{"count":70},"Freshmarket":{"count":86},"Froiz":{"count":97},"Føtex":{"count":74},"G20":{"count":71},"GS25":{"count":72},"Gadis":{"count":126},"Game":{"count":59},"Giant":{"count":276},"Giant Eagle":{"count":134},"Grand Frais":{"count":70},"Grocery Outlet":{"count":128},"Géant Casino":{"count":75},"H-E-B":{"count":274},"HIT":{"count":64},"Hannaford":{"count":95},"Harris Teeter":{"count":158},"Hemköp":{"count":87},"Heron Foods":{"count":55},"Hofer":{"count":484},"Hoogvliet":{"count":66},"Hruška":{"count":54},"Hy-Vee":{"count":121},"ICA":{"count":255},"ICA Kvantum":{"count":51},"IDEA":{"count":52},"IGA":{"count":568},"Iceland":{"count":538},"Indomaret":{"count":124},"Intermarché":{"count":1477},"Intermarché Contact":{"count":122},"Intermarché Super":{"count":261},"Interspar":{"count":117},"Irma":{"count":69},"Jewel-Osco":{"count":72},"Jumbo":{"count":476},"K+K":{"count":119},"Kaufland":{"count":1172},"King Soopers":{"count":99},"Kiwi":{"count":178},"Konsum":{"count":144},"Konzum":{"count":370},"Kroger":{"count":627},"Kvickly":{"count":60},"La Vie Claire":{"count":65},"Landi":{"count":54},"Leader Price":{"count":502},"Leclerc Drive":{"count":120},"Lewiatan":{"count":255},"Lider":{"count":78},"Lidl":{"count":8927},"Londis":{"count":52},"Lupa":{"count":79},"M&S Simply Food":{"count":52},"MPREIS":{"count":187},"Makro":{"count":226},"Markant":{"count":98},"Market Basket":{"count":57},"Marktkauf":{"count":117},"Match":{"count":139},"Maxi":{"count":198},"Maxi Dia":{"count":52},"Maxima":{"count":111},"Maxima X":{"count":158},"Maxima XX":{"count":69},"Mega Image":{"count":97},"Mego":{"count":52},"Meijer":{"count":129},"Meny":{"count":105},"Mercado":{"count":63},"Mercado Municipal":{"count":52},"Mercado de Abastos":{"count":57},"Mercadona":{"count":1228},"Mercator":{"count":155},"Merkur":{"count":132},"Metro":{"count":395},"Migros":{"count":641},"Mila":{"count":90},"Mini Market":{"count":81},"Minimarket":{"count":69},"Minipreço":{"count":213},"Mix Markt":{"count":60},"Monoprix":{"count":283},"More":{"count":61},"Morrisons":{"count":443},"NETTO":{"count":4429},"NORMA":{"count":144},"NP":{"count":251},"Nah & Frisch":{"count":107},"Nahkauf":{"count":324},"Netto Marken-Discount":{"count":706},"New World":{"count":89},"No Frills":{"count":177},"Norfa XL":{"count":66},"Norma":{"count":1162},"Oxxo":{"count":278},"PENNY":{"count":89},"PLUS":{"count":92},"POLOmarket":{"count":172},"Palí":{"count":69},"Pam":{"count":77},"Penny":{"count":2819},"Penny Markt":{"count":77},"Petit Casino":{"count":146},"Pick n Pay":{"count":268},"Piggly Wiggly":{"count":103},"Pingo Doce":{"count":308},"Piotr i Paweł":{"count":112},"Plaza Vea":{"count":68},"Plodine":{"count":67},"Poiesz":{"count":53},"Price Chopper":{"count":132},"Prix":{"count":53},"Profi":{"count":203},"Proxi":{"count":75},"Proxy Delhaize":{"count":63},"Publix":{"count":645},"Punto Simply":{"count":54},"Puregold":{"count":75},"Pão de Açúcar":{"count":76},"QFC":{"count":54},"REMA 1000":{"count":89},"REWE City":{"count":78},"Ralphs":{"count":81},"Real":{"count":210},"Real Canadian Superstore":{"count":69},"Reliance Fresh":{"count":95},"Rema 1000":{"count":394},"Rewe":{"count":2808},"Rimi":{"count":115},"S-Market":{"count":110},"Safeway":{"count":619},"Sainsbury's":{"count":595},"Sainsbury's Local":{"count":248},"Sam's Club":{"count":303},"Santa Isabel":{"count":174},"Save-A-Lot":{"count":100,"tags":{"shop":"supermarket"}},"ShopRite":{"count":53},"Shoprite":{"count":337},"Sigma":{"count":107},"Simply Market":{"count":541},"Sky":{"count":113},"Smith's":{"count":56},"Sobeys":{"count":186},"Soriana":{"count":194},"Spar":{"count":3381},"Społem":{"count":120},"Sprouts Farmers Market":{"count":71},"Stokrotka":{"count":227},"Stop & Shop":{"count":147},"Super C":{"count":57},"Super U":{"count":654},"SuperBrugsen":{"count":183},"SuperValu":{"count":80},"Superama":{"count":51},"Supersol":{"count":51},"Superspar":{"count":54},"Tegut":{"count":118},"Tengelmann":{"count":155},"Tesco":{"count":1373},"Tesco Express":{"count":566},"Tesco Extra":{"count":200},"Tesco Lotus":{"count":95},"Tesco Metro":{"count":153},"The Co-operative":{"count":79},"The Co-operative Food":{"count":1261},"Tommy":{"count":56},"Tottus":{"count":82},"Trader Joe's":{"count":345},"Treff 3000":{"count":134},"U Express":{"count":129},"Unimarc":{"count":256},"Unimarkt":{"count":104},"Utile":{"count":68},"Vea":{"count":67},"Vival":{"count":80},"Volg":{"count":231},"Waitrose":{"count":301},"Walmart":{"count":1164},"Walmart Neighborhood Market":{"count":171},"Walmart Supercenter":{"count":688},"Wasgau":{"count":51},"Wegmans":{"count":89},"Wellcome":{"count":51},"Whole Foods Market":{"count":379,"tags":{"shop":"supermarket"}},"Willys":{"count":89},"WinCo Foods":{"count":53},"Winn Dixie":{"count":168},"Woolworths":{"count":816},"denn's Biomarkt":{"count":147},"fakta":{"count":296},"real":{"count":58},"tegut":{"count":89},"Şok":{"count":271},"Żabka":{"count":88},"ΑΒ Βασιλόπουλος":{"count":82},"Γαλαξίας":{"count":54},"Μασούτης":{"count":85},"Σκλαβενίτης":{"count":92},"АТБ":{"count":618},"Абсолют":{"count":51},"Авоська":{"count":60},"Азбука Вкуса":{"count":66},"Атак":{"count":85},"Ашан":{"count":80},"Верный":{"count":226},"Виктория":{"count":74},"Вопак":{"count":59},"Гастроном":{"count":54},"Гроздь":{"count":63},"Десяточка":{"count":52},"Дикси":{"count":1670},"Евроопт":{"count":201},"Карусель":{"count":68},"Квартал":{"count":77},"Кировский":{"count":54},"Командор":{"count":75},"Красный Яр":{"count":58},"Лента":{"count":165},"Магнит":{"count":4289},"Магнолия":{"count":121},"Мария-Ра":{"count":159},"Монетка":{"count":363},"Народная 7Я семьЯ":{"count":199},"Перекресток":{"count":501},"Покупочка":{"count":73},"Полушка":{"count":213},"Пятёрочка":{"count":3622},"Радеж":{"count":64},"Рукавичка":{"count":78},"Светофор":{"count":73},"Седьмой континент":{"count":69},"Семейный":{"count":52},"Семья":{"count":85},"Супермаркет":{"count":65},"Сільпо":{"count":203},"Таврія‑В":{"count":66},"Универсам":{"count":77},"Фора":{"count":162},"Фуршет":{"count":86},"Хүнсний дэлгүүр":{"count":63},"Эдельвейс":{"count":55},"хүнсний дэлгүүр":{"count":73},"بقالة":{"count":74},"سوپر مارکت":{"count":75},"سوپرمارکت":{"count":79},"いなげや":{"count":66},"まいばすけっと":{"count":162},"イオン":{"count":95},"イトーヨーカドー":{"count":67},"カスミ":{"count":56},"マックスバリュ":{"count":143},"マルエツ":{"count":99},"ライフ":{"count":125},"全聯":{"count":74},"全聯福利中心":{"count":241},"惠康 Wellcome":{"count":57},"業務スーパー":{"count":176},"美廉社":{"count":74},"西友":{"count":137}},"tailor":{"Atelier de couture":{"count":63}},"tattoo":{"Tattoo":{"count":73}},"ticket":{"Boutique Grandes Lignes":{"count":60},"Guichet Transilien":{"count":243},"Касса":{"count":61},"Проездные билеты":{"count":65}},"tobacco":{"Dohánybolt":{"count":109},"Estanco":{"count":134},"Nemzeti Dohánybolt":{"count":926},"Tabacos":{"count":62},"Табакерка":{"count":73}},"toys":{"Dráčik":{"count":63},"Intertoys":{"count":242},"King Jouet":{"count":102},"La Grande Récré":{"count":112},"Maxi Toys":{"count":63},"Toys R Us":{"count":410,"tags":{"shop":"toys"}},"Детский мир":{"count":186},"Игрушки":{"count":95}},"travel_agency":{"D-reizen":{"count":64},"DER Reisebüro":{"count":52},"First Reisebüro":{"count":57},"Flight Centre":{"count":159},"Reiseland":{"count":52},"TUI":{"count":262},"The Co-operative Travel":{"count":58},"Thomas Cook":{"count":298},"Thomson":{"count":144}},"tyres":{"Borracharia":{"count":98},"Bridgestone":{"count":65},"Discount Tire":{"count":94},"Euromaster":{"count":76},"Firestone":{"count":57},"Gomeria":{"count":71},"Les Schwab Tire Center":{"count":59},"Vianor":{"count":52},"Vulcanizing Shop":{"count":54},"Вулканизация":{"count":113},"Шиномонтаж":{"count":419}},"variety_store":{"Action":{"count":147},"Bazar":{"count":56},"Big Bazar":{"count":60},"Big Lots":{"count":65},"Dollar General":{"count":345},"Dollar Tree":{"count":753},"Dollarama":{"count":404},"EuroShop":{"count":59},"Family Dollar":{"count":590},"Fix Price":{"count":97},"Fix price":{"count":127},"FixPrice":{"count":62},"GiFi":{"count":229},"Home Bargains":{"count":68},"Mäc-Geiz":{"count":59},"NOZ":{"count":82},"Poundland":{"count":197},"Poundworld":{"count":70},"Tedi":{"count":611},"ダイソー":{"count":226}},"video":{"Blockbuster":{"count":75},"Family Video":{"count":113},"TSUTAYA":{"count":122},"World of Video":{"count":53},"ゲオ":{"count":81}},"video_games":{"EB Games":{"count":101},"Game":{"count":76},"GameStop":{"count":676},"Micromania":{"count":83}}};
18598 var tourism = {"alpine_hut":{"КОШ":{"count":105}},"apartment":{"Двухкомнатная квартира на сутки":{"count":52}},"attraction":{"Arch":{"count":51},"Kursächsische Postmeilensäule":{"count":54},"Lavoir":{"count":109},"Maibaum":{"count":52},"Moab trail":{"count":55},"Moai":{"count":702},"OWŚ":{"count":102},"Sommerrodelbahn":{"count":54},"path continues":{"count":71},"path contiunes":{"count":75},"white blaze":{"count":53},"Кладбище еврейское":{"count":89},"Колесо обозрения":{"count":69},"Приусадебный парк":{"count":69},"Усадьба":{"count":53},"Хозяйственный двор":{"count":72},"Часовня":{"count":64},"дольмен":{"count":86}},"camp_site":{"Camping Municipal":{"count":198},"Camping municipal":{"count":80},"Campsite":{"count":70}},"guest_house":{"Casa":{"count":61},"Guest House":{"count":64},"Home":{"count":68},"OW \"Bielanka\"":{"count":54}},"hostel":{"Albergue de Peregrinos":{"count":67},"Hospedaje":{"count":70},"Hostal":{"count":124}},"hotel":{"B&B Hôtel":{"count":104},"B&b Hôtel":{"count":78},"Best Western":{"count":242},"Campanile":{"count":145},"Central Hotel":{"count":51},"City Hotel":{"count":74},"Comfort Inn":{"count":283},"Comfort Inn & Suites":{"count":67},"Comfort Suites":{"count":148},"Country Inn & Suites":{"count":83},"Courtyard by Marriott":{"count":155},"Crowne Plaza":{"count":85},"Days Inn":{"count":245},"Econo Lodge":{"count":70},"Embassy Suites":{"count":68},"Extended Stay America":{"count":102},"Fairfield Inn":{"count":60},"Fairfield Inn & Suites":{"count":67},"Formule 1":{"count":74},"Grand Hotel":{"count":90},"Hampton Inn":{"count":376},"Hampton Inn & Suites":{"count":96},"Hilton Garden Inn":{"count":183},"Holiday Inn":{"count":411},"Holiday Inn Express":{"count":479},"Holiday Inn Express & Suites":{"count":72},"Homewood Suites":{"count":61},"Hotel Central":{"count":92},"Hotel Europa":{"count":91},"Hotel Ibis":{"count":67},"Hotel Krone":{"count":58},"Hotel Panorama":{"count":61},"Hotel Plaza":{"count":62},"Hotel Post":{"count":60},"Hotel Royal":{"count":62},"Hotel Victoria":{"count":71},"Hotel zur Post":{"count":60},"Hôtel Ibis":{"count":70},"Hôtel de France":{"count":61},"Ibis":{"count":215},"Ibis Budget":{"count":188},"Ibis Styles":{"count":53},"Krone":{"count":68},"Kyriad":{"count":65},"La Quinta":{"count":54},"Marriott":{"count":57},"Mercure":{"count":109},"Motel 6":{"count":83},"Novotel":{"count":180},"Palace Hotel":{"count":54},"Park Hotel":{"count":88},"Parkhotel":{"count":64},"Premier Inn":{"count":400},"Première Classe":{"count":62},"Quality Inn":{"count":178},"Quality Inn & Suites":{"count":80},"Ramada":{"count":97},"Residence Inn":{"count":89},"Royal Hotel":{"count":94},"Sheraton":{"count":56},"Sleep Inn":{"count":68},"Staybridge Suites":{"count":54},"Super 8":{"count":229},"Travelodge":{"count":284},"Гостиница":{"count":166},"Уют":{"count":58},"東横イン":{"count":57}},"motel":{"Best Western":{"count":59},"Budget Inn":{"count":76},"Comfort Inn":{"count":131},"Days Inn":{"count":103},"Econo Lodge":{"count":117},"Motel":{"count":105},"Motel 6":{"count":214},"Quality Inn":{"count":113},"Rodeway Inn":{"count":102},"Super 8":{"count":173},"Travelodge":{"count":68}},"museum":{"Heimatmuseum":{"count":336},"Museum":{"count":51},"Stadtmuseum":{"count":86},"Tájház":{"count":93},"Краеведческий музей":{"count":247},"Музей":{"count":99}}};
18599 var dataSuggestions = {
18600         amenity: amenity,
18601         leisure: leisure,
18602         man_made: man_made,
18603         shop: shop,
18604         tourism: tourism
18605 };
18606
18607 var dataAddressFormats = [{"format":[["housenumber","street","unit"],["city","postcode"]]},{"countryCodes":["gb"],"format":[["housename"],["housenumber","street","unit"],["city","postcode"]]},{"countryCodes":["ie"],"format":[["housename"],["housenumber","street","unit"],["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":[["unit","street","housenumber"],["postcode","city"]]},{"countryCodes":["fr","lu","mo"],"format":[["unit","housenumber","street"],["postcode","city"]]},{"countryCodes":["br"],"format":[["street","unit"],["housenumber","suburb"],["city","postcode"]]},{"countryCodes":["vn"],"format":[["housenumber","street"],["subdistrict"],["district"],["city"],["province","postcode"]]},{"countryCodes":["au","ca"],"format":[["housenumber","street","unit"],["city","province","postcode"]]},{"countryCodes":["us"],"format":[["housenumber","street","unit"],["city","state","postcode"]]},{"countryCodes":["tw"],"format":[["postcode","city","district"],["place","street"],["housenumber","floor","unit"]]},{"countryCodes":["jp"],"format":[["postcode","province","county"],["city","suburb"],["quarter","neighbourhood"],["block_number","housenumber"]],"dropdowns":["postcode","province","county","city","suburb","quarter","neighbourhood","block_number"],"widths":{"postcode":0.3,"province":0.35,"county":0.35,"city":0.65,"suburb":0.35,"quarter":0.5,"neighbourhood":0.5,"block_number":0.5,"housenumber":0.5}},{"countryCodes":["tr"],"format":[["neighbourhood"],["street","housenumber","unit"],["postcode","district","city"]]},{"countryCodes":["ua"],"format":[["housenumber","postcode"],["street","unit"]]},{"countryCodes":["cn"],"format":[["postcode","province"],["city","district"],["street","housenumber"]]}];
18608
18609 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"}}];
18610
18611 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"];
18612
18613 var dataLocales = {"af":{"rtl":false},"ar":{"rtl":true},"ar-AA":{"rtl":true},"ast":{"rtl":false},"bg":{"rtl":false},"bg-BG":{"rtl":false},"bn":{"rtl":false},"bs":{"rtl":false},"ca":{"rtl":false},"cs":{"rtl":false},"da":{"rtl":false},"de":{"rtl":false},"dv":{"rtl":true},"el":{"rtl":false},"en-GB":{"rtl":false},"eo":{"rtl":false},"es":{"rtl":false},"et":{"rtl":false},"eu":{"rtl":false},"fa":{"rtl":true},"fi":{"rtl":false},"fr":{"rtl":false},"gan":{"rtl":false},"gl":{"rtl":false},"gu":{"rtl":false},"he":{"rtl":true},"hi":{"rtl":false},"hr":{"rtl":false},"hu":{"rtl":false},"hy":{"rtl":false},"ia":{"rtl":false},"id":{"rtl":false},"is":{"rtl":false},"it":{"rtl":false},"ja":{"rtl":false},"jv":{"rtl":false},"km":{"rtl":false},"kn":{"rtl":false},"ko":{"rtl":false},"ku":{"rtl":true},"lij":{"rtl":false},"lt":{"rtl":false},"lv":{"rtl":false},"mg":{"rtl":false},"mk":{"rtl":false},"ml":{"rtl":false},"mn":{"rtl":false},"ms":{"rtl":false},"ne":{"rtl":false},"nl":{"rtl":false},"nn":{"rtl":false},"no":{"rtl":false},"nv":{"rtl":false},"pl":{"rtl":false},"pt":{"rtl":false},"pt-BR":{"rtl":false},"rm":{"rtl":false},"ro":{"rtl":false},"ru":{"rtl":false},"sc":{"rtl":false},"si":{"rtl":false},"sk":{"rtl":false},"sl":{"rtl":false},"sq":{"rtl":false},"sr":{"rtl":false},"sv":{"rtl":false},"ta":{"rtl":false},"te":{"rtl":false},"th":{"rtl":false},"tl":{"rtl":false},"tr":{"rtl":false},"uk":{"rtl":false},"ur":{"rtl":true},"vi":{"rtl":false},"yue":{"rtl":false},"zh":{"rtl":false},"zh-CN":{"rtl":false},"zh-HK":{"rtl":false},"zh-TW":{"rtl":false}};
18614
18615 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","ie":"+353 20 912 3456","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 1632 961234","gg":"+44 1632 961234","im":"+44 1632 961234","je":"+44 1632 961234","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 1234 5678","cn":"+86 10 12345678","tw":"+886 1 2345 6789","tr":"+90 312 123 4567","ua":"+380 44 123 4567"};
18616
18617 var dataShortcuts = [{"tab":"browsing","text":"shortcuts.browsing.title","columns":[{"rows":[{"section":"navigation","text":"shortcuts.browsing.navigation.title"},{"shortcuts":["↓","↑","←","→"],"text":"shortcuts.browsing.navigation.pan","separator":","},{"modifiers":["⌘"],"shortcuts":["↓","↑","←","→"],"text":"shortcuts.browsing.navigation.pan_more","separator":","},{"shortcuts":["+","-"],"text":"shortcuts.browsing.navigation.zoom","separator":","},{"modifiers":["⌘"],"shortcuts":["+","-"],"text":"shortcuts.browsing.navigation.zoom_more","separator":","},{"section":"help","text":"shortcuts.browsing.help.title"},{"shortcuts":["help.key"],"text":"shortcuts.browsing.help.help"},{"shortcuts":["shortcuts.toggle.key"],"text":"shortcuts.browsing.help.keyboard"},{"section":"display_options","text":"shortcuts.browsing.display_options.title"},{"shortcuts":["background.key"],"text":"shortcuts.browsing.display_options.background"},{"modifiers":["⌘"],"shortcuts":["background.key"],"text":"shortcuts.browsing.display_options.background_switch"},{"shortcuts":["map_data.key"],"text":"shortcuts.browsing.display_options.map_data"},{"modifiers":["⌃","⌘"],"shortcuts":["F","F11"],"text":"shortcuts.browsing.display_options.fullscreen"},{"shortcuts":["area_fill.wireframe.key"],"text":"shortcuts.browsing.display_options.wireframe"},{"shortcuts":["background.minimap.key"],"text":"shortcuts.browsing.display_options.minimap"}]},{"rows":[{"section":"selecting","text":"shortcuts.browsing.selecting.title"},{"shortcuts":["Left-click"],"text":"shortcuts.browsing.selecting.select_one"},{"modifiers":["⇧"],"shortcuts":["Left-click"],"text":"shortcuts.browsing.selecting.select_multi"},{"modifiers":["⇧"],"shortcuts":["Left-click"],"gesture":"shortcuts.gesture.drag","text":"shortcuts.browsing.selecting.lasso"},{"shortcuts":[],"text":""},{"section":"with_selected","text":"shortcuts.browsing.with_selected.title"},{"shortcuts":["Right-click","shortcuts.key.space"],"text":"shortcuts.browsing.with_selected.edit_menu"},{"shortcuts":[],"text":""},{"section":"vertex_selected","text":"shortcuts.browsing.vertex_selected.title"},{"shortcuts":["[","↖"],"text":"shortcuts.browsing.vertex_selected.previous"},{"shortcuts":["]","↘"],"text":"shortcuts.browsing.vertex_selected.next"},{"shortcuts":["{","⇞"],"text":"shortcuts.browsing.vertex_selected.first"},{"shortcuts":["}","⇟"],"text":"shortcuts.browsing.vertex_selected.last"},{"shortcuts":["\\","shortcuts.key.pause"],"text":"shortcuts.browsing.vertex_selected.change_parent"}]}]},{"tab":"editing","text":"shortcuts.editing.title","columns":[{"rows":[{"section":"drawing","text":"shortcuts.editing.drawing.title"},{"shortcuts":["1"],"text":"shortcuts.editing.drawing.add_point"},{"shortcuts":["2"],"text":"shortcuts.editing.drawing.add_line"},{"shortcuts":["3"],"text":"shortcuts.editing.drawing.add_area"},{"shortcuts":["Left-click","shortcuts.key.space"],"text":"shortcuts.editing.drawing.place_point"},{"shortcuts":["⌥"],"text":"shortcuts.editing.drawing.disable_snap"},{"shortcuts":["↵","⎋"],"text":"shortcuts.editing.drawing.stop_line"},{"section":"commands","text":"shortcuts.editing.commands.title"},{"modifiers":["⌘"],"shortcuts":["C"],"text":"shortcuts.editing.commands.copy"},{"modifiers":["⌘"],"shortcuts":["V"],"text":"shortcuts.editing.commands.paste"},{"modifiers":["⌘"],"shortcuts":["Z"],"text":"shortcuts.editing.commands.undo"},{"modifiers":["⌘","⇧"],"shortcuts":["Z"],"text":"shortcuts.editing.commands.redo"},{"modifiers":["⌘"],"shortcuts":["S"],"text":"shortcuts.editing.commands.save"}]},{"rows":[{"section":"operations","text":"shortcuts.editing.operations.title"},{"shortcuts":["operations.continue.key"],"text":"shortcuts.editing.operations.continue_line"},{"shortcuts":["operations.merge.key"],"text":"shortcuts.editing.operations.merge"},{"shortcuts":["operations.disconnect.key"],"text":"shortcuts.editing.operations.disconnect"},{"shortcuts":["operations.split.key"],"text":"shortcuts.editing.operations.split"},{"shortcuts":["operations.reverse.key"],"text":"shortcuts.editing.operations.reverse"},{"shortcuts":["operations.move.key"],"text":"shortcuts.editing.operations.move"},{"shortcuts":["operations.rotate.key"],"text":"shortcuts.editing.operations.rotate"},{"shortcuts":["operations.orthogonalize.key"],"text":"shortcuts.editing.operations.orthogonalize"},{"shortcuts":["operations.circularize.key"],"text":"shortcuts.editing.operations.circularize"},{"shortcuts":["operations.reflect.key.long"],"text":"shortcuts.editing.operations.reflect_long"},{"shortcuts":["operations.reflect.key.short"],"text":"shortcuts.editing.operations.reflect_short"},{"modifiers":["⌘"],"shortcuts":["⌫"],"text":"shortcuts.editing.operations.delete"}]}]},{"tab":"tools","text":"shortcuts.tools.title","columns":[{"rows":[{"section":"info","text":"shortcuts.tools.info.title"},{"modifiers":["⌘"],"shortcuts":["info_panels.key"],"text":"shortcuts.tools.info.all"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.background.key"],"text":"shortcuts.tools.info.background"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.history.key"],"text":"shortcuts.tools.info.history"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.location.key"],"text":"shortcuts.tools.info.location"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.measurement.key"],"text":"shortcuts.tools.info.measurement"}]}]}];
18618
18619 var type = "FeatureCollection";
18620 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]]]}}];
18621 var dataImperial = {
18622         type: type,
18623         features: features
18624 };
18625
18626 var type$1 = "FeatureCollection";
18627 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]]]}}];
18628 var dataDriveLeft = {
18629         type: type$1,
18630         features: features$1
18631 };
18632
18633 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":{"single":"Delete this feature permanently.","multiple":"Delete these features 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} features."},"too_large":{"single":"This feature can't be deleted because not enough of it is currently visible.","multiple":"These features can't be deleted because not enough of them are currently visible."},"incomplete_relation":{"single":"This feature can't be deleted because it hasn't been fully downloaded.","multiple":"These features can't be deleted because they haven't been fully downloaded."},"part_of_relation":{"single":"This feature can't be deleted because it is part of a larger relation. You must remove it from the relation first.","multiple":"These features can't be deleted because they are part of larger relations. You must remove them from the relations first."},"connected_to_hidden":{"single":"This feature can't be deleted because it is connected to a hidden feature.","multiple":"These features can't be deleted because some are connected to hidden features."}},"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 their endpoints 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":{"single":"Move this feature to a different location.","multiple":"Move these features 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 features."},"incomplete_relation":{"single":"This feature can't be moved because it hasn't been fully downloaded.","multiple":"These features can't be moved because they haven't been fully downloaded."},"too_large":{"single":"This feature can't be moved because not enough of it is currently visible.","multiple":"These features can't be moved because not enough of them are currently visible."},"connected_to_hidden":{"single":"This feature can't be moved because it is connected to a hidden feature.","multiple":"These features can't be moved because some are connected to hidden features."}},"reflect":{"title":{"long":"Reflect Long","short":"Reflect Short"},"description":{"long":{"single":"Reflect this feature across its long axis.","multiple":"Reflect these features across their long axis."},"short":{"single":"Reflect this feature across its short axis.","multiple":"Reflect these features across their short axis."}},"key":{"long":"T","short":"Y"},"annotation":{"long":{"single":"Reflected a feature across its long axis.","multiple":"Reflected multiple features across their long axis."},"short":{"single":"Reflected a feature across its short axis.","multiple":"Reflected multiple features across their short axis."}},"incomplete_relation":{"single":"This feature can't be reflected because it hasn't been fully downloaded.","multiple":"These features can't be reflected because they haven't been fully downloaded."},"too_large":{"single":"This feature can't be reflected because not enough of it is currently visible.","multiple":"These features can't be reflected because not enough of them are currently visible."},"connected_to_hidden":{"single":"This feature can't be reflected because it is connected to a hidden feature.","multiple":"These features can't be reflected because some are connected to hidden features."}},"rotate":{"title":"Rotate","description":{"single":"Rotate this feature around its center point.","multiple":"Rotate these features around their center point."},"key":"R","annotation":{"line":"Rotated a line.","area":"Rotated an area.","multiple":"Rotated multiple features."},"incomplete_relation":{"single":"This feature can't be rotated because it hasn't been fully downloaded.","multiple":"These features can't be rotated because they haven't been fully downloaded."},"too_large":{"single":"This feature can't be rotated because not enough of it is currently visible.","multiple":"These features can't be rotated because not enough of them are currently visible."},"connected_to_hidden":{"single":"This feature can't be rotated because it is connected to a hidden feature.","multiple":"These features can't be rotated because some are connected to hidden features."}},"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":"Upload to OpenStreetMap","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.","request_review":"I would like someone to review my edits.","save":"Upload","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"},"info_panels":{"key":"I","background":{"key":"B","title":"Background","zoom":"Zoom","vintage":"Vintage","unknown":"Unknown","show_tiles":"Show Tiles","hide_tiles":"Hide Tiles"},"history":{"key":"H","title":"History","selected":"{n} selected","version":"Version","last_edit":"Last Edit","edited_by":"Edited By","changeset":"Changeset","unknown":"Unknown","link_text":"History on openstreetmap.org"},"location":{"key":"L","title":"Location","unknown_location":"Unknown Location"},"measurement":{"key":"M","title":"Measurement","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 features","unknown":"Unknown","incomplete":"<not downloaded>","feature_list":"Search features","edit":"Edit feature","check":{"yes":"Yes","no":"No","reverser":"Change Direction"},"radio":{"structure":{"type":"Type","default":"Default","layer":"Layer"}},"add":"Add","none":"None","node":"Node","way":"Way","relation":"Relation","location":"Location","add_fields":"Add field:"},"background":{"title":"Background","description":"Background settings","key":"B","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:\n   - {zoom}/{z}, {x}, {y} for Z/X/Y tile scheme\n   - {ty} for flipped TMS-style Y coordinates\n   - {u} for quadtile scheme\n   - {switch:a,b,c} for DNS server multiplexing\n\nExample:\n{example}","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.","key":"/"}},"map_data":{"title":"Map Data","description":"Map Data","key":"F","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.","key":"W"},"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 my changes","reset":"Discard my changes"},"save":{"title":"Save","help":"Review your changes and upload them 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 feature 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 feature has been deleted by {user}.","location":"This feature 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":"OK","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"},"version":{"whats_new":"What's new in iD {version}"},"tag_reference":{"description":"Description","on_wiki":"{tag} on wiki.osm.org","used_with":"used with {type}"},"validations":{"disconnected_highway":"Disconnected highway","disconnected_highway_tooltip":"Roads should be connected to other roads or building entrances.","old_multipolygon":"Multipolygon tags on outer way","old_multipolygon_tooltip":"This style of multipolygon is deprecated. Please assign the tags to the parent multipolygon instead of the outer way.","untagged_point":"Untagged point","untagged_point_tooltip":"Select a feature type that describes what this point is.","untagged_line":"Untagged line","untagged_line_tooltip":"Select a feature type that describes what this line is.","untagged_area":"Untagged area","untagged_area_tooltip":"Select a feature type that describes what this area is.","untagged_relation":"Untagged relation","untagged_relation_tooltip":"Select a feature type that describes what this relation is.","many_deletions":"You're deleting {n} features. 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","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 file","drag_drop":"Drag and drop a .gpx, .geojson or .kml file on the page, or click the button to the right to browse","zoom":"Zoom to layer","browse":"Browse for a 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","key":"H","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\nYou can view a list of keyboard shortcuts by pressing the `?` key.\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","ok":"OK","graph":{"block_number":"<value for addr:block_number>","city":"Three Rivers","county":"<value for addr:county>","district":"<value for addr:district>","hamlet":"<value for addr:hamlet>","neighbourhood":"<value for addr:neighbourhood>","postcode":"49093","province":"<value for addr:province>","quarter":"<value for addr:quarter>","state":"MI","subdistrict":"<value for addr:subdistrict>","suburb":"<value for addr:suburb>","countrycode":"us","name":{"1st-avenue":"1st Avenue","2nd-avenue":"2nd Avenue","4th-avenue":"4th Avenue","5th-avenue":"5th Avenue","6th-avenue":"6th Avenue","6th-street":"6th Street","7th-avenue":"7th Avenue","8th-avenue":"8th Avenue","9th-avenue":"9th Avenue","10th-avenue":"10th Avenue","11th-avenue":"11th Avenue","12th-avenue":"12th Avenue","access-point-employment":"Access Point Employment","adams-street":"Adams Street","andrews-elementary-school":"Andrews Elementary School","andrews-street":"Andrews Street","armitage-street":"Armitage Street","barrows-school":"Barrows School","battle-street":"Battle Street","bennett-street":"Bennett Street","bowman-park":"Bowman Park","collins-drive":"Collins Drive","conrail-railroad":"Conrail Railroad","conservation-park":"Conservation Park","constantine-street":"Constantine Street","cushman-street":"Cushman Street","dollar-tree":"Dollar Tree","douglas-avenue":"Douglas Avenue","east-street":"East Street","elm-street":"Elm Street","flower-street":"Flower Street","foster-street":"Foster Street","french-street":"French Street","garden-street":"Garden Street","gem-pawnbroker":"Gem Pawnbroker","golden-finch-framing":"Golden Finch Framing","grant-avenue":"Grant Avenue","hoffman-pond":"Hoffman Pond","hoffman-street":"Hoffman Street","hook-avenue":"Hook Avenue","jefferson-street":"Jefferson Street","kelsey-street":"Kelsey Street","lafayette-park":"LaFayette Park","las-coffee-cafe":"L.A.'s Coffee Cafe","lincoln-avenue":"Lincoln Avenue","lowrys-books":"Lowry's Books","lynns-garage":"Lynn's Garage","main-street-barbell":"Main Street Barbell","main-street-cafe":"Main Street Cafe","main-street-fitness":"Main Street Fitness","main-street":"Main Street","maple-street":"Maple Street","marina-park":"Marina Park","market-street":"Market Street","memory-isle-park":"Memory Isle Park","memory-isle":"Memory Isle","michigan-avenue":"Michigan Avenue","middle-street":"Middle Street","millard-street":"Millard Street","moore-street":"Moore Street","morris-avenue":"Morris Avenue","mural-mall":"Mural Mall","paisanos-bar-and-grill":"Paisano's Bar and Grill","paisley-emporium":"Paisley Emporium","paparazzi-tattoo":"Paparazzi Tattoo","pealer-street":"Pealer Street","pine-street":"Pine Street","pizza-hut":"Pizza Hut","portage-avenue":"Portage Avenue","portage-river":"Portage River","preferred-insurance-services":"Preferred Insurance Services","railroad-drive":"Railroad Drive","river-city-appliance":"River City Appliance","river-drive":"River Drive","river-road":"River Road","river-street":"River Street","riverside-cemetery":"Riverside Cemetery","riverwalk-trail":"Riverwalk Trail","riviera-theatre":"Riviera Theatre","rocky-river":"Rocky River","saint-joseph-river":"Saint Joseph River","scidmore-park-petting-zoo":"Scidmore Park Petting Zoo","scidmore-park":"Scidmore Park","scouter-park":"Scouter Park","sherwin-williams":"Sherwin-Williams","south-street":"South Street","southern-michigan-bank":"Southern Michigan Bank","spring-street":"Spring Street","sturgeon-river-road":"Sturgeon River Road","three-rivers-city-hall":"Three Rivers City Hall","three-rivers-elementary-school":"Three Rivers Elementary School","three-rivers-fire-department":"Three Rivers Fire Department","three-rivers-high-school":"Three Rivers High School","three-rivers-middle-school":"Three Rivers Middle School","three-rivers-municipal-airport":"Three Rivers Municipal Airport","three-rivers-post-office":"Three Rivers Post Office","three-rivers-public-library":"Three Rivers Public Library","three-rivers":"Three Rivers","unique-jewelry":"Unique Jewelry","walnut-street":"Walnut Street","washington-street":"Washington Street","water-street":"Water Street","west-street":"West Street","wheeler-street":"Wheeler Street","william-towing":"William Towing","willow-drive":"Willow Drive","wood-street":"Wood Street","world-fare":"World Fare"}},"welcome":{"title":"Welcome","welcome":"Welcome! This walkthrough will teach you the basics of editing on OpenStreetMap.","practice":"All of the data in this walkthrough is just for practicing, and any edits that you make in the walkthrough will not be saved.","words":"This walkthrough will introduce some new words and concepts. When we introduce a new word, we'll use *italics*.","mouse":"You can use any input device to edit the map, but this walkthrough assumes you have a mouse with left and right buttons. **If you want to attach a mouse, do so now, then click OK.**","leftclick":"When this tutorial asks you to click or double-click, we mean with the left button. On a trackpad it might be a single-click or single-finger tap. **Left-click {num} times.**","rightclick":"Sometimes we'll also ask you to right-click. This might be the same as control-click, or two-finger tap on a trackpad. Your keyboard might even have a 'menu' key that works like right-click. **Right-click {num} times.**","chapters":"So far, so good! You can use the buttons below to skip chapters at any time or to restart a chapter if you get stuck. Let's begin! **Click '{next}' to continue.**"},"navigation":{"title":"Navigation","drag":"The main map area shows OpenStreetMap data on top of a background.{br}You can drag the map by pressing and holding the left mouse button while moving the mouse around. You can also use the arrow keys on your keyboard. **Drag the map!**","zoom":"You can zoom in or out by scrolling with the mouse wheel or trackpad, or by clicking the {plus} / {minus} buttons. **Zoom the map!**","features":"We use the word *features* to describe the things that appear on the map. Anything in the real world can be mapped as a feature on OpenStreetMap.","points_lines_areas":"Map features are represented using *points, lines, or areas.*","nodes_ways":"In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*.","click_townhall":"All features on the map can be selected by clicking on them. **Click on the point to select it.**","selected_townhall":"Great! The point is now selected. Selected features are drawn with a pulsing glow.","editor_townhall":"When a feature is selected, the *feature editor* is displayed alongside the map.","preset_townhall":"The top part of the feature editor shows the feature's type. This point is a {preset}.","fields_townhall":"The middle part of the feature editor contains *fields* showing the feature's attributes, such as its name and address.","close_townhall":"**Close the feature editor by hitting escape or pressing the {button} button in the upper corner.**","search_street":"You can also search for features in the current view, or worldwide. **Search for '{name}'.**","choose_street":"**Choose {name} from the list to select it.**","selected_street":"Great! {name} is now selected.","editor_street":"The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by hitting escape or pressing the {button} button.**","play":"Try moving the map and clicking on some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**"},"points":{"title":"Points","add_point":"*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**","place_point":"To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**","search_cafe":"There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**","choose_cafe":"**Choose {preset} from the list.**","feature_editor":"The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe.","add_name":"In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**","add_close":"The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or 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 cafe you just created.**","update":"Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**","update_close":"**When you are finished updating the cafe, hit escape, enter, or click the {button} button to close the feature editor.**","rightclick":"You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Right-click to select the point you created and show the edit menu.**","delete":"It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Click on the {button} button to delete the point.**","undo":"You can always undo any changes up until you save your edits to OpenStreetMap. **Click on the {button} button to undo the delete and get the point back.**","play":"Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, click '{next}'.**"},"areas":{"title":"Areas","add_playground":"*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}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.**","start_playground":"Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**","continue_playground":"Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**","finish_playground":"Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**","search_playground":"**Search for '{preset}'.**","choose_playground":"**Choose {preset} from the list.**","add_field":"This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**","choose_field":"**Choose {field} from the list.**","retry_add_field":"You didn't select the {field} field. Let's try again.","describe_playground":"**Add a description, then click the {button} button to close the feature editor.**","play":"Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**"},"lines":{"title":"Lines","add_line":"*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**","start_line":"Here is a road that is missing. Let's add it!{br}In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary. **Start a new line by clicking at the top end of this missing road.**","intersect":"Click or press spacebar to add more nodes to the line.{br}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.**","retry_intersect":"The road needs to intersect {name}. Let's try again!","continue_line":"Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.{br}When you are finished drawing, click on the last node again. **Finish drawing the road.**","choose_category_road":"**Select {category} from the list.**","choose_preset_residential":"There are many different types of roads, but this one is a residential road. **Choose the {preset} type.**","retry_preset_residential":"You didn't select the {preset} type. **Click here to choose again.**","name_road":"**Give this road a name, then hit escape, enter, or click the {button} button to close the feature editor.**","did_name_road":"Looks good! Next we will learn how to update the shape of a line.","update_line":"Sometimes you will need to change the shape of an existing line. Here is a road that doesn't look quite right.","add_node":"We can add some nodes to this line to improve its shape. One way to add a node is to double-click the line where you want to add a node. **Double-click on the line to create a new node.**","start_drag_endpoint":"When a line is selected, you can drag any of its nodes by clicking and holding down the left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**","finish_drag_endpoint":"This spot looks good. **Release the left mouse button to finish dragging.**","start_drag_midpoint":"Small triangles are drawn at the *midpoints* between nodes. Another way to create a new node is to drag a midpoint to a new location. **Drag the midpoint triangle to create a new node along the curve of the road.**","continue_drag_midpoint":"This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click OK.**","delete_lines":"It's OK to delete lines for roads that don't exist in the real world.{br}Here's an example where the city planned a {street} but never built it. We can improve this part of the map by deleting the extra lines.","rightclick_intersection":"The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **Right click on the intersection node.**","split_intersection":"**Click on the {button} button to split {street}.**","retry_split":"You didn't click the Split button. Try again.","did_split_multi":"Good job! {street1} is now split into two pieces. The top part can be removed. **Click the top part of {street2} to select it.**","did_split_single":"**Click the top part of {street2} to select it.**","multi_select":"{selected} is now selected. Let's also select {other1}. You can shift-click to select multiple things. **Shift-click on {other2}.**","multi_rightclick":"Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**","multi_delete":"**Click on the {button} button to delete the extra lines.**","retry_delete":"You didn't click the Delete button. Try again.","play":"Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, click '{next}'.**"},"buildings":{"title":"Buildings","add_building":"OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**","start_building":"Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**","continue_building":"Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**","retry_building":"It looks like you had some trouble placing the nodes at the building corners. Try again!","choose_category_building":"**Choose {category} from the list.**","choose_preset_house":"There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**","close":"**Hit escape or click the {button} button to close the feature editor.**","rightclick_building":"**Right-click to select the building you created and show the edit menu.**","square_building":"The house that you just added will look even better with perfectly square corners. **Click on the {button} button to square the building shape.**","retry_square":"You didn't click the Square button. Try again.","done_square":"See how the corners of the building moved into place? Let's learn another useful trick.","add_tank":"Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**","start_tank":"Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**","continue_tank":"Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**","search_tank":"**Search for '{preset}'.**","choose_tank":"**Choose {preset} from the list.**","rightclick_tank":"**Right-click to select the storage tank you created and show the edit menu.**","circle_tank":"**Click on the {button} button to make the tank a circle.**","retry_circle":"You didn't click the Circularize button. Try again.","play":"Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, click '{next}'.**"},"startediting":{"title":"Start Editing","help":"You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by clicking the {button} Help button or pressing the '{key}' key.","shortcuts":"You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key.","save":"Don't forget to regularly save your changes!","start":"Start mapping!"}},"shortcuts":{"title":"Keyboard shortcuts","tooltip":"Show the keyboard shortcuts screen.","toggle":{"key":"?"},"key":{"alt":"Alt","backspace":"Backspace","cmd":"Cmd","ctrl":"Ctrl","delete":"Delete","del":"Del","end":"End","enter":"Enter","esc":"Esc","home":"Home","option":"Option","pause":"Pause","pgdn":"PgDn","pgup":"PgUp","return":"Return","shift":"Shift","space":"Space"},"gesture":{"drag":"drag"},"or":"-or-","browsing":{"title":"Browsing","navigation":{"title":"Navigation","pan":"Pan map","pan_more":"Pan map by one screenful","zoom":"Zoom in / Zoom out","zoom_more":"Zoom in / Zoom out by a lot"},"help":{"title":"Help","help":"Show help/documentation","keyboard":"Show keyboard shortcuts"},"display_options":{"title":"Display options","background":"Show background options","background_switch":"Switch back to last background","map_data":"Show map data options","fullscreen":"Enter full screen mode","wireframe":"Toggle wireframe mode","minimap":"Toggle minimap"},"selecting":{"title":"Selecting features","select_one":"Select a single feature","select_multi":"Select multiple features","lasso":"Draw a selection lasso around features"},"with_selected":{"title":"With feature selected","edit_menu":"Toggle edit menu"},"vertex_selected":{"title":"With node selected","previous":"Jump to previous node","next":"Jump to next node","first":"Jump to first node","last":"Jump to last node","change_parent":"Switch parent way"}},"editing":{"title":"Editing","drawing":{"title":"Drawing","add_point":"'Add point' mode","add_line":"'Add line' mode","add_area":"'Add area' mode","place_point":"Place a point","disable_snap":"Hold to disable point snapping","stop_line":"Finish drawing a line or area"},"operations":{"title":"Operations","continue_line":"Continue a line at the selected node","merge":"Combine (merge) selected features","disconnect":"Disconnect features at the selected node","split":"Split a line into two at the selected node","reverse":"Reverse a line","move":"Move selected features","rotate":"Rotate selected features","orthogonalize":"Straighten line / Square area corners","circularize":"Circularize a closed line or area","reflect_long":"Reflect features across the longer axis","reflect_short":"Reflect features across the shorter axis","delete":"Delete selected features"},"commands":{"title":"Commands","copy":"Copy selected features","paste":"Paste copied features","undo":"Undo last action","redo":"Redo last action","save":"Save changes"}},"tools":{"title":"Tools","info":{"title":"Information","all":"Toggle all information panels","background":"Toggle background panel","history":"Toggle history panel","location":"Toggle location panel","measurement":"Toggle measurement panel"}}},"presets":{"categories":{"category-barrier":{"name":"Barrier Features"},"category-building":{"name":"Building Features"},"category-golf":{"name":"Golf Features"},"category-landuse":{"name":"Land Use Features"},"category-natural-area":{"name":"Natural Features"},"category-natural-line":{"name":"Natural Features"},"category-natural-point":{"name":"Natural 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":{"block_number":"Block Number","block_number!jp":"Block No.","city":"City","city!jp":"City/Town/Village/Tokyo Special Ward","city!vn":"City/Town","conscriptionnumber":"123","country":"Country","county":"County","county!jp":"District","district":"District","district!vn":"Arrondissement/Town/District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","housenumber!jp":"Building No./Lot No.","neighbourhood":"Neighbourhood","neighbourhood!jp":"Chōme/Aza/Koaza","place":"Place","postcode":"Postcode","province":"Province","province!jp":"Prefecture","quarter":"Quarter","quarter!jp":"Ōaza/Machi","state":"State","street":"Street","subdistrict":"Subdistrict","subdistrict!vn":"Ward/Commune/Townlet","suburb":"Suburb","suburb!jp":"Ward","unit":"Unit"}},"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"},"animal_boarding":{"label":"For Animals"},"animal_breeding":{"label":"For Animals"},"animal_shelter":{"label":"For Animals"},"area/highway":{"label":"Type"},"artist":{"label":"Artist"},"artwork_type":{"label":"Type"},"atm":{"label":"ATM"},"backrest":{"label":"Backrest"},"barrier":{"label":"Type"},"bath/open_air":{"label":"Open Air"},"bath/sand_bath":{"label":"Sand Bath"},"bath/type":{"label":"Specialty","options":{"onsen":"Japanese Onsen","foot_bath":"Foot Bath","hot_spring":"Hot Spring"}},"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"},"bridge":{"label":"Type","placeholder":"Default"},"building_area":{"label":"Building"},"building":{"label":"Building"},"bunker_type":{"label":"Type"},"camera/direction":{"label":"Direction (Degrees Clockwise)","placeholder":"45, 90, 180, 270"},"camera/mount":{"label":"Camera Mount"},"camera/type":{"label":"Camera Type","options":{"fixed":"Fixed","panning":"Panning","dome":"Dome"}},"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"}},"castle_type":{"label":"Type"},"clock_direction":{"label":"Direction","options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}},"clothes":{"label":"Clothes"},"club":{"label":"Type"},"collection_times":{"label":"Collection Times"},"comment":{"label":"Changeset Comment","placeholder":"Brief description of your contributions (required)"},"communication_multi":{"label":"Communication Types"},"construction":{"label":"Type"},"contact/webcam":{"label":"Webcam URL","placeholder":"http://example.com/"},"content":{"label":"Content"},"country":{"label":"Country"},"covered":{"label":"Covered"},"craft":{"label":"Type"},"crop":{"label":"Crops"},"crossing":{"label":"Type"},"cuisine":{"label":"Cuisines"},"currency_multi":{"label":"Currency Types"},"cutting":{"label":"Type","placeholder":"Default"},"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"},"email":{"label":"Email","placeholder":"example@example.com"},"embankment":{"label":"Type","placeholder":"Default"},"emergency":{"label":"Emergency"},"entrance":{"label":"Type"},"except":{"label":"Exceptions"},"fax":{"label":"Fax","placeholder":"+31 42 123 4567"},"fee":{"label":"Fee"},"fence_type":{"label":"Type"},"fire_hydrant/position":{"label":"Position","options":{"lane":"Lane","parking_lot":"Parking Lot","sidewalk":"Sidewalk","green":"Green"}},"fire_hydrant/type":{"label":"Type","options":{"pillar":"Pillar/Aboveground","underground":"Underground","wall":"Wall","pond":"Pond"}},"fixme":{"label":"Fix Me"},"ford":{"label":"Type","placeholder":"Default"},"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/output/electricity":{"label":"Power Output","placeholder":"50 MW, 100 MW, 200 MW..."},"generator/source":{"label":"Source"},"generator/type":{"label":"Type"},"grape_variety":{"label":"Grape Varieties"},"handicap":{"label":"Handicap","placeholder":"1-18"},"handrail":{"label":"Handrail"},"hashtags":{"label":"Hashtags","placeholder":"#example"},"height":{"label":"Height (Meters)"},"highway":{"label":"Type"},"historic":{"label":"Type"},"historic/civilization":{"label":"Historic Civilization"},"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"},"inscription":{"label":"Inscription"},"internet_access":{"label":"Internet Access","options":{"yes":"Yes","no":"No","wlan":"Wifi","wired":"Wired","terminal":"Terminal"}},"internet_access/fee":{"label":"Internet Access Fee"},"internet_access/ssid":{"label":"SSID (Network Name)"},"kerb":{"label":"Curb"},"label":{"label":"Label"},"lamp_type":{"label":"Type"},"landuse":{"label":"Type"},"lanes":{"label":"Lanes","placeholder":"1, 2, 3..."},"layer":{"label":"Layer","placeholder":"0"},"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"},"manhole":{"label":"Type"},"map_size":{"label":"Coverage"},"map_type":{"label":"Type"},"maxheight":{"label":"Max Height","placeholder":"4, 4.5, 5, 14'0\", 14'6\", 15'0\""},"maxspeed":{"label":"Speed Limit","placeholder":"40, 50, 60..."},"maxstay":{"label":"Max Stay"},"maxweight":{"label":"Max Weight"},"milestone_position":{"label":"Milestone Position","placeholder":"Distance to one decimal (123.4)"},"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"},"outdoor_seating":{"label":"Outdoor Seating"},"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"},"plant":{"label":"Plant"},"plant/output/electricity":{"label":"Power Output","placeholder":"500 MW, 1000 MW, 2000 MW..."},"population":{"label":"Population"},"power_supply":{"label":"Power Supply"},"power":{"label":"Type"},"produce":{"label":"Produce"},"product":{"label":"Products"},"railway":{"label":"Type"},"recycling_accepts":{"label":"Accepts"},"recycling_type":{"label":"Recycling Type","options":{"container":"Container","centre":"Recycling Center"}},"ref_aeroway_gate":{"label":"Gate Number"},"ref_golf_hole":{"label":"Hole Number","placeholder":"1-18"},"ref_highway_junction":{"label":"Junction Number"},"ref_platform":{"label":"Platform Number"},"ref_road_number":{"label":"Road Number"},"ref_route":{"label":"Route Number"},"ref_runway":{"label":"Runway Number","placeholder":"e.g. 01L/19R"},"ref_stop_position":{"label":"Stop Number"},"ref_taxiway":{"label":"Taxiway Name","placeholder":"e.g. A5"},"ref":{"label":"Reference Code"},"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_times":{"label":"Service Times"},"service":{"label":"Type"},"service/bicycle":{"label":"Services"},"service/vehicle":{"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"},"social_facility":{"label":"Type"},"source":{"label":"Sources"},"sport_ice":{"label":"Sports"},"sport_racing_motor":{"label":"Sports"},"sport_racing_nonmotor":{"label":"Sports"},"sport":{"label":"Sports"},"stars":{"label":"Stars"},"start_date":{"label":"Start Date"},"step_count":{"label":"Number of Steps"},"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"},"surveillance":{"label":"Surveillance Kind"},"surveillance/type":{"label":"Surveillance Type","options":{"camera":"Camera","guard":"Guard","ALPR":"Automatic License Plate Reader"}},"surveillance/zone":{"label":"Surveillance Zone"},"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"}},"toll":{"label":"Toll"},"tomb":{"label":"Type"},"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_waterway":{"label":"Tunnel"},"tunnel":{"label":"Type","placeholder":"Default"},"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)"}},"wall":{"label":"Type"},"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/drag_lift":{"name":"Drag Lift","terms":""},"aerialway/gondola":{"name":"Gondola","terms":""},"aerialway/goods":{"name":"Goods Aerialway","terms":""},"aerialway/magic_carpet":{"name":"Magic Carpet Lift","terms":""},"aerialway/mixed_lift":{"name":"Mixed 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":"tbar"},"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/coworking_space":{"name":"Coworking Space","terms":""},"amenity/nursing_home":{"name":"Nursing Home","terms":""},"amenity/register_office":{"name":"Register Office","terms":""},"amenity/swimming_pool":{"name":"Swimming Pool","terms":""},"amenity/animal_boarding":{"name":"Animal Boarding Facility","terms":"boarding,cat,dog,horse,kitten,pet boarding,pet care,pet hotel,puppy,reptile"},"amenity/animal_breeding":{"name":"Animal Breeding Facility","terms":"breeding,bull,cat,cow,dog,horse,husbandry,kitten,livestock,pet breeding,puppy,reptile"},"amenity/animal_shelter":{"name":"Animal Shelter","terms":"adoption,aspca,cat,dog,horse,kitten,pet care,pet rescue,puppy,raptor,reptile,rescue,spca"},"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/crematorium":{"name":"Crematorium","terms":"cemetery,funeral"},"amenity/dentist":{"name":"Dentist","terms":"tooth,teeth"},"amenity/doctors":{"name":"Doctor","terms":"medic*,physician"},"amenity/dojo":{"name":"Dojo / Martial Arts Academy","terms":"martial arts,dojang"},"amenity/drinking_water":{"name":"Drinking Water","terms":"fountain,potable"},"amenity/driving_school":{"name":"Driving School","terms":""},"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/food_court":{"name":"Food Court","terms":"fast food,restaurant,food"},"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,infirmary,institution,sanatorium,sanitarium,sick,surgery,ward"},"amenity/hunting_stand":{"name":"Hunting Stand","terms":"game,gun,lookout,rifle,shoot*,wild,watch"},"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/pavilion":{"name":"Pavilion","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/hindu":{"name":"Hindu Temple","terms":"garbhargriha,mandu,puja,shrine,temple"},"amenity/place_of_worship/jewish":{"name":"Synagogue","terms":"jewish"},"amenity/place_of_worship/muslim":{"name":"Mosque","terms":"muslim"},"amenity/place_of_worship/shinto":{"name":"Shinto Shrine","terms":"kami,torii"},"amenity/place_of_worship/sikh":{"name":"Sikh Temple","terms":"gurudwara,temple"},"amenity/place_of_worship/taoist":{"name":"Taoist Temple","terms":"daoist,monastery,temple"},"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":"alcohol,drink,dive,beer,bier,booze"},"amenity/public_bath":{"name":"Public Bath","terms":"onsen,foot bath,hot springs"},"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/scrapyard":{"name":"Scrap Yard","terms":"car,junk,metal,salvage,scrap,u-pull-it,vehicle,wreck,yard"},"amenity/shelter":{"name":"Shelter","terms":"lean-to,gazebo,picnic"},"amenity/shower":{"name":"Shower","terms":"rain closet"},"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,care home,assisted living"},"amenity/social_facility/homeless_shelter":{"name":"Homeless Shelter","terms":"houseless,unhoused,displaced"},"amenity/social_facility/nursing_home":{"name":"Nursing Home","terms":"elderly,living,nursing,old,senior,assisted living"},"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":{"name":"Vending Machine","terms":""},"amenity/vending_machine/news_papers":{"name":"Newspaper Vending Machine","terms":"newspaper"},"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/newspapers":{"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/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/waste/dog_excrement":{"name":"Dog Excrement Bin","terms":"bin,garbage,rubbish,litter,trash,poo,dog"},"amenity/water_point":{"name":"RV Drinking Water","terms":""},"amenity/watering_place":{"name":"Animal Watering Place","terms":""},"area":{"name":"Area","terms":""},"area/highway":{"name":"Road Surface","terms":""},"attraction/amusement_ride":{"name":"Amusement Ride","terms":"theme park,carnival ride"},"attraction/animal":{"name":"Animal","terms":"zoo,theme park,animal park,lion,tiger,bear"},"attraction/big_wheel":{"name":"Big Wheel","terms":"ferris wheel,theme park,amusement ride"},"attraction/bumper_car":{"name":"Bumper Car","terms":"theme park,dodgem cars,autoscooter"},"attraction/bungee_jumping":{"name":"Bungee Jumping","terms":"theme park,bungy jumping,jumping platform"},"attraction/carousel":{"name":"Carousel","terms":"theme park,roundabout,merry-go-round,galloper,jumper,horseabout,flying horses"},"attraction/dark_ride":{"name":"Dark Ride","terms":"theme park,ghost train"},"attraction/drop_tower":{"name":"Drop Tower","terms":"theme park,amusement ride,gondola,tower,big drop"},"attraction/pirate_ship":{"name":"Pirate Ship","terms":"theme park,carnival ride,amusement ride"},"attraction/river_rafting":{"name":"River Rafting","terms":"theme park,aquatic park,water park,rafting simulator,river rafting ride,river rapids ride"},"attraction/roller_coaster":{"name":"Roller Coaster","terms":"theme park,amusement ride"},"attraction/train":{"name":"Tourist Train","terms":"theme park,rackless train,road train,Tschu-Tschu train,dotto train,park train"},"attraction/water_slide":{"name":"Water Slide","terms":"theme park,aquatic park,water park,flumes,water chutes,hydroslides"},"barrier":{"name":"Barrier","terms":""},"barrier/entrance":{"name":"Entrance","terms":""},"barrier/block":{"name":"Block","terms":""},"barrier/bollard":{"name":"Bollard","terms":""},"barrier/border_control":{"name":"Border Control","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"},"club":{"name":"Club","terms":"social"},"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":"alcohol,beer,beverage,bier,booze,cider"},"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/distillery":{"name":"Distillery","terms":"alcohol,beverage,bourbon,booze,brandy,gin,hooch,liquor,mezcal,moonshine,rum,scotch,spirits,still,tequila,vodka,whiskey,whisky"},"craft/dressmaker":{"name":"Dressmaker","terms":"seamstress"},"craft/electrician":{"name":"Electrician","terms":"power,wire"},"craft/electronics_repair":{"name":"Electronics Repair Shop","terms":""},"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":"fire plug"},"emergency/life_ring":{"name":"Life Ring","terms":"life buoy,kisby ring,kisbie ring,perry buoy"},"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/elevator":{"name":"Elevator","terms":"lift"},"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":"autobahn,expressway,freeway,highway,interstate,parkway,thruway,turnpike"},"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":"Racetrack (Motorsport)","terms":"auto*,formula one,kart,motocross,nascar,race*,track"},"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/speed_camera":{"name":"Speed Camera","terms":""},"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_mirror":{"name":"Traffic Mirror","terms":"blind spot,convex,corner,curved,roadside,round,safety,sphere,visibility"},"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/tomb":{"name":"Tomb","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/aquaculture":{"name":"Aquaculture","terms":"fish farm,crustacean,algae,aquafarming,shrimp farm,oyster farm,mariculture,algaculture"},"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":"crop,grow,plant"},"landuse/farmyard":{"name":"Farmyard","terms":"crop,grow,plant"},"landuse/forest":{"name":"Forest","terms":"tree"},"landuse/garages":{"name":"Garages","terms":""},"landuse/grass":{"name":"Grass","terms":""},"landuse/harbour":{"name":"Harbor","terms":"boat"},"landuse/industrial":{"name":"Industrial Area","terms":""},"landuse/landfill":{"name":"Landfill","terms":"dump"},"landuse/meadow":{"name":"Meadow","terms":""},"landuse/military":{"name":"Military Area","terms":""},"landuse/military/airfield":{"name":"Military Airfield","terms":"air force,army,base,bomb,fight,force,guard,heli*,jet,marine,navy,plane,troop,war"},"landuse/military/barracks":{"name":"Barracks","terms":"air force,army,base,fight,force,guard,marine,navy,troop,war"},"landuse/military/bunker":{"name":"Military Bunker","terms":"air force,army,base,fight,force,guard,marine,navy,troop,war"},"landuse/military/checkpoint":{"name":"Checkpoint","terms":"air force,army,base,force,guard,marine,navy,troop,war"},"landuse/military/danger_area":{"name":"Danger Area","terms":"air force,army,base,blast,bomb,explo*,force,guard,mine,marine,navy,troop,war"},"landuse/military/naval_base":{"name":"Naval Base","terms":"base,fight,force,guard,marine,navy,ship,sub,troop,war"},"landuse/military/nuclear_explosion_site":{"name":"Nuclear Explosion Site","terms":"atom,blast,bomb,detonat*,nuke,site,test"},"landuse/military/obstacle_course":{"name":"Obstacle Course","terms":"army,base,force,guard,marine,navy,troop,war"},"landuse/military/office":{"name":"Military Office","terms":"air force,army,base,enlist,fight,force,guard,marine,navy,recruit,troop,war"},"landuse/military/range":{"name":"Military Range","terms":"air force,army,base,fight,fire,force,guard,gun,marine,navy,rifle,shoot*,snip*,train,troop,war"},"landuse/military/training_area":{"name":"Training Area","terms":"air force,army,base,fight,fire,force,guard,gun,marine,navy,rifle,shoot*,snip*,train,troop,war"},"landuse/orchard":{"name":"Orchard","terms":"fruit"},"landuse/plant_nursery":{"name":"Plant Nursery","terms":"flower,garden,grow,vivero"},"landuse/quarry":{"name":"Quarry","terms":""},"landuse/railway":{"name":"Railway Corridor","terms":"rail,train,track"},"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":"grape,wine"},"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/dance":{"name":"Dance Hall","terms":"ballroom,jive,swing,tango,waltz"},"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/horse_riding":{"name":"Horseback Riding Facility","terms":"equestrian,stable"},"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/beachvolleyball":{"name":"Beach Volleyball Court","terms":"volleyball"},"leisure/pitch/bowls":{"name":"Bowling Green","terms":""},"leisure/pitch/cricket":{"name":"Cricket Field","terms":""},"leisure/pitch/equestrian":{"name":"Riding Arena","terms":"dressage,equestrian,horse,horseback,riding"},"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":"football"},"leisure/pitch/table_tennis":{"name":"Ping Pong Table","terms":"table tennis,ping pong"},"leisure/pitch/tennis":{"name":"Tennis Court","terms":""},"leisure/pitch/volleyball":{"name":"Volleyball Court","terms":""},"leisure/playground":{"name":"Playground","terms":"jungle gym,play area"},"leisure/resort":{"name":"Resort","terms":""},"leisure/running_track":{"name":"Racetrack (Running)","terms":"race*,running,sprint,track"},"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":"cycle,dog,greyhound,horse,race*,track"},"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":"Mast","terms":"antenna,broadcast tower,cell phone tower,cell tower,communication mast,communication tower,guyed tower,mobile phone tower,radio mast,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,jetty"},"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_camera":{"name":"Surveillance Camera","terms":"anpr,alpr,camera,car plate recognition,cctv,guard,license plate recognition,monitoring,number plate recognition,security,video,webcam"},"man_made/surveillance":{"name":"Surveillance","terms":"anpr,alpr,camera,car plate recognition,cctv,guard,license plate recognition,monitoring,number plate recognition,security,video,webcam"},"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/watermill":{"name":"Watermill","terms":"water,wheel,mill"},"man_made/windmill":{"name":"Windmill","terms":"wind,wheel,mill"},"man_made/works":{"name":"Factory","terms":"assembly,build,brewery,car,plant,plastic,processing,manufacture,refinery"},"manhole":{"name":"Manhole","terms":"cover,hole,sewer,sewage,telecom"},"manhole/drain":{"name":"Storm Drain","terms":"cover,drain,hole,rain,sewer,sewage,storm"},"manhole/telecom":{"name":"Telecom Manhole","terms":"cover,phone,hole,telecom,telephone,bt"},"natural":{"name":"Natural","terms":""},"natural/bare_rock":{"name":"Bare Rock","terms":"rock"},"natural/bay":{"name":"Bay","terms":""},"natural/beach":{"name":"Beach","terms":"shore"},"natural/cave_entrance":{"name":"Cave Entrance","terms":"cavern,hollow,grotto,shelter,cavity"},"natural/cliff":{"name":"Cliff","terms":"escarpment"},"natural/coastline":{"name":"Coastline","terms":"shore"},"natural/fell":{"name":"Fell","terms":""},"natural/glacier":{"name":"Glacier","terms":""},"natural/grassland":{"name":"Grassland","terms":"prairie,savanna"},"natural/heath":{"name":"Heath","terms":""},"natural/peak":{"name":"Peak","terms":"acme,aiguille,alp,climax,crest,crown,hill,mount,mountain,pinnacle,summit,tip,top"},"natural/ridge":{"name":"Ridge","terms":"crest"},"natural/saddle":{"name":"Saddle","terms":"pass,mountain pass,top"},"natural/sand":{"name":"Sand","terms":"desert"},"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":"bog,marsh,reedbed,swamp,tidalflat"},"natural/wood":{"name":"Wood","terms":"tree"},"noexit/yes":{"name":"No Exit","terms":"no exit,road end,dead end"},"office":{"name":"Office","terms":""},"office/physician":{"name":"Physician","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/coworking":{"name":"Coworking Space","terms":"coworking,office"},"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/lawyer/notary":{"name":"Notary Office","terms":"clerk,signature,wills,deeds,estate"},"office/newspaper":{"name":"Newspaper","terms":""},"office/ngo":{"name":"NGO Office","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/farm":{"name":"Farm","terms":""},"place/city":{"name":"City","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/quarter":{"name":"Sub-Borough / Quarter","terms":"boro,borough,quarter"},"place/square":{"name":"Square","terms":""},"place/suburb":{"name":"Borough / Suburb","terms":"boro,borough,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":"hydro,solar,turbine,wind"},"power/generator/source_nuclear":{"name":"Nuclear Reactor","terms":"fission,generator,nuclear,nuke,reactor"},"power/generator/source_wind":{"name":"Wind Turbine","terms":"generator,turbine,windmill,wind"},"power/line":{"name":"Power Line","terms":""},"power/minor_line":{"name":"Minor Power Line","terms":""},"power/plant":{"name":"Power Station Grounds","terms":"coal,gas,generat*,hydro,nuclear,power,station"},"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/buffer_stop":{"name":"Buffer Stop","terms":"stop,halt,buffer"},"railway/crossing":{"name":"Railway Crossing (Path)","terms":"crossing,pedestrian crossing,railroad crossing,level crossing,grade crossing,path through railroad,train crossing"},"railway/derail":{"name":"Railway Derailer","terms":"derailer"},"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/milestone":{"name":"Railway Milestone","terms":"milestone,marker"},"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/signal":{"name":"Railway Signal","terms":"signal,lights"},"railway/station":{"name":"Railway Station","terms":"train station,station"},"railway/subway_entrance":{"name":"Subway Entrance","terms":"metro,transit"},"railway/subway":{"name":"Subway","terms":"metro,transit"},"railway/switch":{"name":"Railway Switch","terms":"switch,points"},"railway/train_wash":{"name":"Train Wash","terms":"wash,clean"},"railway/tram_stop":{"name":"Tram Stop","terms":"light rail,streetcar,tram,trolley"},"railway/tram":{"name":"Tram","terms":"light rail,streetcar,tram,trolley"},"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/appliance":{"name":"Appliance Store","terms":"air conditioner,appliance,dishwasher,dryer,freezer,fridge,grill,kitchen,oven,refrigerator,stove,washer,washing machine"},"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,blueray,camera,computer,dvd,home theater,radio,speaker,tv,video"},"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/gas":{"name":"Bottled Gas Shop","terms":"cng,lpg,natural gas,propane,refill,tank"},"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/perfumery":{"name":"Perfume Store","terms":""},"shop/pet":{"name":"Pet Store","terms":"animal,cat,dog,fish,kitten,puppy,reptile"},"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/watches":{"name":"Watches Shop","terms":""},"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/aquarium":{"name":"Aquarium","terms":"fish,sea,water"},"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":"signpost"},"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":"animal"},"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/waterfall":{"name":"Waterfall","terms":"fall"},"waterway/weir":{"name":"Weir","terms":""}}},"imagery":{"Bing":{"description":"Satellite and aerial imagery.","name":"Bing aerial imagery"},"DigitalGlobe-Premium":{"attribution":{"text":"Terms & Feedback"},"description":"Premium DigitalGlobe satellite imagery.","name":"DigitalGlobe Premium Imagery"},"DigitalGlobe-Standard":{"attribution":{"text":"Terms & Feedback"},"description":"Standard DigitalGlobe satellite imagery.","name":"DigitalGlobe Standard Imagery"},"EsriWorldImagery":{"attribution":{"text":"Terms & Feedback"},"description":"Esri world imagery.","name":"Esri World Imagery"},"MAPNIK":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"description":"The default OpenStreetMap layer.","name":"OpenStreetMap (Standard)"},"Mapbox":{"attribution":{"text":"Terms & Feedback"},"description":"Satellite and aerial imagery.","name":"Mapbox Satellite"},"New_and_Misaligned_TIGER_Roads-2013":{"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","name":"New & Misaligned TIGER Roads"},"OSM_Inspector-Addresses":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Addresses"},"OSM_Inspector-Geometry":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Geometry"},"OSM_Inspector-Highways":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Highways"},"OSM_Inspector-Multipolygon":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Area"},"OSM_Inspector-Places":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Places"},"OSM_Inspector-Routing":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Routing"},"OSM_Inspector-Tagging":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Tagging"},"Waymarked_Trails-Cycling":{"attribution":{"text":"© Sarah Hoffmann, CC by-SA 3.0, map data OpenStreetMap contributors, ODbL 1.0"},"name":"Waymarked Trails: Cycling"},"Waymarked_Trails-Hiking":{"attribution":{"text":"© Sarah Hoffmann, CC by-SA 3.0, map data OpenStreetMap contributors, ODbL 1.0"},"name":"Waymarked Trails: Hiking"},"Waymarked_Trails-MTB":{"attribution":{"text":"© Sarah Hoffmann, CC by-SA 3.0, map data OpenStreetMap contributors, ODbL 1.0"},"name":"Waymarked Trails: MTB"},"Waymarked_Trails-Skating":{"attribution":{"text":"© Sarah Hoffmann, CC by-SA 3.0, map data OpenStreetMap contributors, ODbL 1.0"},"name":"Waymarked Trails: Skating"},"Waymarked_Trails-Winter_Sports":{"attribution":{"text":"© Michael Spreng, CC by-SA 3.0, map data OpenStreetMap contributors, ODbL 1.0"},"name":"Waymarked Trails: Winter Sports"},"basemap.at":{"attribution":{"text":"basemap.at"},"description":"Basemap of Austria, based on goverment data.","name":"basemap.at"},"basemap.at-orthofoto":{"attribution":{"text":"basemap.at"},"description":"Orthofoto layer provided by basemap.at. \"Successor\" of geoimage.at imagery.","name":"basemap.at Orthofoto"},"hike_n_bike":{"attribution":{"text":"© OpenStreetMap contributors"},"name":"Hike & Bike"},"mapbox_locator_overlay":{"attribution":{"text":"Terms & Feedback"},"description":"Shows major features to help orient you.","name":"Locator Overlay"},"openpt_map":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"name":"OpenPT Map (overlay)"},"osm-gps":{"attribution":{"text":"© OpenStreetMap contributors"},"description":"Public GPS traces uploaded to OpenStreetMap.","name":"OpenStreetMap GPS traces"},"osm-mapnik-black_and_white":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"name":"OpenStreetMap (Standard Black & White)"},"osm-mapnik-german_style":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"name":"OpenStreetMap (German Style)"},"qa_no_address":{"attribution":{"text":"Simon Poole, Data ©OpenStreetMap contributors"},"name":"QA No Address"},"skobbler":{"attribution":{"text":"© Tiles: skobbler Map data: OpenStreetMap contributors"},"name":"skobbler"},"stamen-terrain-background":{"attribution":{"text":"Map tiles by Stamen Design, under CC BY 3.0"},"name":"Stamen Terrain"},"tf-cycle":{"attribution":{"text":"Maps © Thunderforest, Data © OpenStreetMap contributors"},"name":"Thunderforest OpenCycleMap"},"tf-landscape":{"attribution":{"text":"Maps © Thunderforest, Data © OpenStreetMap contributors"},"name":"Thunderforest Landscape"}}};
18634
18635 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}","endDate":"2013-06-01T00:00:00.000Z","startDate":"2013-05-01T00:00:00.000Z","scaleExtent":[0,19],"polygon":[[[-123.02167396992,48.44667085335],[-122.9466579482,48.44780949945],[-122.90151100606,48.41306930778],[-122.80263405293,48.40771378918],[-122.79199104756,48.44279926564],[-122.8088138625,48.47865708877],[-122.73911934346,48.49572334021],[-122.78546791524,48.62160819278],[-122.73087959737,48.6361306644],[-122.75559883565,48.71207854113],[-122.95747261494,48.71592956034],[-122.97086220235,48.695765074],[-122.99970131367,48.69780454658],[-123.00347786397,48.73427448605],[-123.04330330342,48.74310484148],[-123.0762622878,48.70528190578],[-123.08484535664,48.66334903433],[-123.12844734639,48.66380254936],[-123.22698097676,48.70301615666],[-123.24655037373,48.68352650341],[-123.17445259541,48.64701977542],[-123.21513634175,48.60106537642],[-123.21393471211,48.57335906966],[-123.18080406636,48.56574853208],[-123.16621284932,48.52006125122],[-123.10235481709,48.47683634964],[-123.02167396992,48.44667085335]],[[-122.98339348286,48.78214357977],[-122.93498497456,48.76653172572],[-122.91181068867,48.73857664785],[-122.80229073018,48.73982194177],[-122.81945686787,48.75498940888],[-122.93429832906,48.79571515892],[-122.98373680562,48.79435816618],[-122.98339348286,48.78214357977]]],"description":"Public domain aerial imagery taken in May/June 2013 from San Juan County, WA. Resolution is 9 inch."},{"id":"sjcgis.org-Aerials_2016_WM","name":"2016 aerial imagery for San Juan County WA","type":"tms","template":"http://sjcgis.org/arcgis/rest/services/Basemaps/Aerials_2016_WM/MapServer/tile/{zoom}/{y}/{x}","endDate":"2016-07-01T00:00:00.000Z","startDate":"2016-05-01T00:00:00.000Z","scaleExtent":[0,19],"polygon":[[[-123.02167396992,48.44667085335],[-122.9466579482,48.44780949945],[-122.90151100606,48.41306930778],[-122.80263405293,48.40771378918],[-122.79199104756,48.44279926564],[-122.8088138625,48.47865708877],[-122.73911934346,48.49572334021],[-122.78546791524,48.62160819278],[-122.73087959737,48.6361306644],[-122.75559883565,48.71207854113],[-122.95747261494,48.71592956034],[-122.97086220235,48.695765074],[-122.99970131367,48.69780454658],[-123.00347786397,48.73427448605],[-123.04330330342,48.74310484148],[-123.0762622878,48.70528190578],[-123.08484535664,48.66334903433],[-123.12844734639,48.66380254936],[-123.22698097676,48.70301615666],[-123.24655037373,48.68352650341],[-123.17445259541,48.64701977542],[-123.21513634175,48.60106537642],[-123.21393471211,48.57335906966],[-123.18080406636,48.56574853208],[-123.16621284932,48.52006125122],[-123.10235481709,48.47683634964],[-123.02167396992,48.44667085335]],[[-122.98339348286,48.78214357977],[-122.93498497456,48.76653172572],[-122.91181068867,48.73857664785],[-122.80229073018,48.73982194177],[-122.81945686787,48.75498940888],[-122.93429832906,48.79571515892],[-122.98373680562,48.79435816618],[-122.98339348286,48.78214357977]]],"best":true,"description":"Public domain aerial imagery taken in May, June, and July from San Juan County, WA. Resolution is 6 inch countywide."},{"id":"OS7","name":"7th Series (OS7)","type":"tms","template":"http://ooc.openstreetmap.org/os7/{zoom}/{x}/{y}.jpg","polygon":[[[-3.046968,54.839473],[-3.058641,55.2415704],[-4.0446639,55.2329572],[-4.0707564,55.6365416],[-4.6190429,55.6253005],[-4.6492553,56.0283381],[-4.4896102,56.0321747],[-4.5239425,56.4367031],[-3.8675094,56.4458128],[-3.8417602,56.049435],[-3.445909,56.0498185],[-3.4349227,55.6442923],[-2.7949691,55.6504917],[-2.8080153,56.0574872],[-3.2066131,56.0532696],[-3.2141662,56.4568175],[-3.7380767,56.4507463],[-3.7418532,56.8617541],[-5.0766921,56.8317131],[-5.0365233,56.4294897],[-5.1601195,56.4249331],[-5.1299071,56.0179772],[-5.9260726,55.994559],[-5.8551764,55.2333487],[-5.2280974,55.2513559],[-5.2102447,55.027647],[-4.659555,55.0418131],[-4.6454787,54.8163344],[-3.046968,54.839473]],[[-1.7483497,57.7642809],[-1.7406468,57.3599979],[-2.5802193,57.3553698],[-2.5743689,57.0452643],[-2.0840782,57.0479899],[-2.0765057,56.6427564],[-2.734497,56.6390587],[-2.737815,56.8171751],[-3.2388513,56.8143725],[-3.2489563,57.351683],[-3.7562947,57.3488858],[-3.7621877,57.6586785],[-4.7658688,57.6447324],[-4.810078,58.2698422],[-5.2511001,58.2654711],[-5.2737594,58.6676722],[-3.5581778,58.6988712],[-3.566072,58.9316035],[-3.3765578,58.9344382],[-3.3858372,59.2017095],[-3.187134,59.2021481],[-3.1874677,59.2417623],[-3.0675673,59.2420266],[-3.0785537,59.4213467],[-2.3713088,59.4276337],[-2.3685622,59.0221982],[-2.678926,59.0207845],[-2.6734328,58.8393493],[-2.8656936,58.8365068],[-2.8602004,58.5353109],[-3.0346084,58.5331604],[-3.0195022,58.1315879],[-3.6155983,58.1198177],[-3.6127639,57.9775439],[-3.7109154,57.9756153],[-3.699316,57.7536442],[-1.7483497,57.7642809]],[[-7.0749164,56.7631857],[-7.7347099,56.7356573],[-7.7911007,57.1399384],[-7.7066243,57.1434261],[-7.7629881,57.5431114],[-7.6021787,57.5496778],[-7.6213373,57.6845215],[-7.724988,57.6803049],[-7.7301746,57.7167278],[-7.6026437,57.7219106],[-7.5996413,57.7008338],[-7.4863439,57.7054402],[-7.49528,57.7681282],[-7.3749316,57.7730121],[-7.3933722,57.9020139],[-7.2359063,57.9083804],[-7.2432312,57.9594843],[-7.1391571,57.9636854],[-7.1450794,58.0049464],[-7.2374247,58.001223],[-7.2329687,57.9701789],[-7.3113276,57.9670164],[-7.3153794,57.9952475],[-7.2490415,57.9979228],[-7.2808211,58.218564],[-7.0735459,58.2268701],[-7.0827038,58.2901845],[-6.807432,58.3011927],[-6.8276802,58.4407359],[-6.5030498,58.4536624],[-6.5153194,58.5379206],[-6.1647379,58.5518417],[-6.1063084,58.1489361],[-6.3346892,58.139764],[-6.2775862,57.7414459],[-6.9613783,57.7136632],[-6.9333168,57.5161471],[-7.100168,57.5093277],[-7.0521806,57.169002],[-7.1311072,57.1657457],[-7.0749164,56.7631857]],[[0.4107642,50.8208689],[0.9810233,50.8061178],[0.9943731,51.0117337],[1.4506241,50.9999804],[1.4771216,51.4055151],[0.8961869,51.4203486],[0.882435,51.2103932],[0.5050041,51.2200721],[0.5227271,51.4904202],[-0.6339669,51.5106322],[-0.6367135,51.4456291],[-1.0995126,51.4524759],[-1.1148479,51.0481357],[-0.5298744,51.0394048],[-0.5275085,51.10203],[0.4280611,51.0877836],[0.4107642,50.8208689]],[[-5.3945661,51.9618998],[-4.7958112,51.9805124],[-4.7887332,51.8940308],[-4.2026458,51.9122773],[-4.2294099,52.2382823],[-3.6551984,52.2560218],[-3.6222764,51.8548323],[-4.2134157,51.836405],[-4.1855134,51.4934202],[-4.776615,51.4748465],[-4.7847576,51.5752482],[-5.0879928,51.5657379],[-5.0942224,51.6424172],[-5.3678001,51.6338498],[-5.3945661,51.9618998]],[[-1.2389016,54.0353696],[-0.6277871,54.0281103],[-0.6200376,54.2525704],[-0.5726819,54.2520109],[-0.5586479,54.6554165],[-1.17998,54.6626853],[-1.1878192,54.4378771],[-1.2322093,54.4383992],[-1.2389016,54.0353696]],[[-2.6722741,50.9767709],[-2.0996118,50.9802295],[-2.1057212,51.3794917],[-1.5887659,51.3825866],[-1.594992,51.7858908],[-2.1756313,51.7889106],[-2.1715392,51.3839176],[-2.6784576,51.3808828],[-2.6722741,50.9767709]],[[-2.6015496,53.2715461],[-3.2297251,53.2685042],[-3.2352183,53.6723131],[-2.6070428,53.6753262],[-2.6015496,53.2715461]],[[-0.0394177,51.7727994],[-0.6156335,51.7757705],[-0.6046472,52.5841377],[-0.0284314,52.5812201],[-0.0394177,51.7727994]],[[-2.9152892,54.0352257],[-3.5322877,54.0286638],[-3.5448438,54.4339736],[-2.9278454,54.4404713],[-2.9152892,54.0352257]],[[-6.3058305,57.1968949],[-6.3538957,57.6001458],[-5.6911121,57.6229455],[-5.643047,57.2199469],[-6.3058305,57.1968949]],[[1.171145,52.5723589],[1.1986505,52.9759408],[1.7978754,52.9610616],[1.7703699,52.5573411],[1.171145,52.5723589]],[[-2.4022508,55.5631737],[-2.4008775,55.9656986],[-1.7608445,55.965011],[-1.7622178,55.562479],[-2.4022508,55.5631737]],[[-6.3257432,56.3853727],[-7.0196021,56.3574652],[-7.0731605,56.7638392],[-6.3793015,56.7914485],[-6.3257432,56.3853727]],[[-2.422577,54.4430983],[-2.4257397,54.841885],[-1.7993058,54.8435404],[-1.7961431,54.4447701],[-2.422577,54.4430983]],[[-3.0270123,51.3793548],[-3.6058877,51.370168],[-3.6223672,51.7730401],[-3.0434918,51.7821458],[-3.0270123,51.3793548]],[[-3.0537915,52.1897924],[-3.0661511,52.5937352],[-2.4836401,52.600342],[-2.4712805,52.1964599],[-3.0537915,52.1897924]],[[-5.676726,51.7042466],[-5.6788616,51.731006],[-5.4635982,51.7375973],[-5.4614627,51.7108418],[-5.676726,51.7042466]],[[-5.8442675,59.1088192],[-5.8469031,59.1357806],[-5.7955763,59.1371015],[-5.7929408,59.1101412],[-5.8442675,59.1088192]],[[-8.648442,57.7786066],[-8.6659651,57.87717],[-8.4664946,57.8872093],[-8.4489714,57.7886733],[-8.648442,57.7786066]],[[-4.5271098,59.0153156],[-4.5285904,59.0331938],[-4.4762337,59.034342],[-4.4747531,59.0164644],[-4.5271098,59.0153156]],[[-7.6806151,58.2583811],[-7.6865455,58.2938023],[-7.5344535,58.3008387],[-7.5285231,58.2654246],[-7.6806151,58.2583811]],[[-6.1910235,59.080087],[-6.1954619,59.1158563],[-6.125424,59.1181472],[-6.1209857,59.0823803],[-6.1910235,59.080087]],[[-4.4266879,59.0711219],[-4.4280472,59.0886998],[-4.3762055,59.089758],[-4.3748462,59.0721806],[-4.4266879,59.0711219]]]},{"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":"lu.geoportail.opendata.basemap","name":"Basemap geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/basemap/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","endDate":"2010-07-20T00:00:00.000Z","startDate":"2013-07-19T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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","scaleExtent":[0,19],"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","description":"Basemap of Austria, based on goverment data.","icon":"https://www.basemap.at/images/logo_basemap.jpg"},{"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","scaleExtent":[0,19],"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,"description":"Orthofoto layer provided by basemap.at. \"Successor\" of geoimage.at imagery.","icon":"https://www.basemap.at/images/logo_basemap.jpg"},{"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":"GRB","name":"Belgium AGIV GRB Flanders","type":"tms","template":"http://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=grb_bsk&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":"GRB Flanders © AGIV","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABm0lEQVQ4y6WTPUgCYRjHf5oFJVfRUZKVHYFBoBAUFLZE0FBD0NQHRENESzS019LSFNHWx1DQEhGRg0JFREM11FJuLWem4GB5HULdwdkgHprn5LO97/O8v+fj/7y2bDabpQKzFx5S6ntlgE81xvHtclHAbuSNloNT5q/uywP021cAvO4hAPYu5/hI5e6GWpsBCEfjxNSMNUALPvJ7eA3AQPcML3KIzbNhlvdEWmu+6RCcAISiCWtA3fosPztBfrYvAGgX/QCIggdR8DDe6Qbg5E0uAdjyKhhykq+uBeySi9qVCfSAB61HRBQ8RFJpRs6vALiZHMUnNpYO0Ujn+jPkJJnVfbTBNeqfFQB8YqP56H8VJqBKcuHcWsQuuXIOyUX1sN8MnPJKlnOwWS2SIScx0hkcvV3mXUzN0HcSAuBoNMBYZxsADittVXcT/XcPKE/PltqHowkTYLcMkOMoml52+wr9jnIZAJZ8XjYGe0vaUDSdsBxnulsqrUDRdMLReNHg8tYhOAs2M2HdQiSVBqChprpI7/9q5JPYKv3OfxL1n52ATYYBAAAAAElFTkSuQmCC"},{"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 © AGIV","best":true,"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABm0lEQVQ4y6WTPUgCYRjHf5oFJVfRUZKVHYFBoBAUFLZE0FBD0NQHRENESzS019LSFNHWx1DQEhGRg0JFREM11FJuLWem4GB5HULdwdkgHprn5LO97/O8v+fj/7y2bDabpQKzFx5S6ntlgE81xvHtclHAbuSNloNT5q/uywP021cAvO4hAPYu5/hI5e6GWpsBCEfjxNSMNUALPvJ7eA3AQPcML3KIzbNhlvdEWmu+6RCcAISiCWtA3fosPztBfrYvAGgX/QCIggdR8DDe6Qbg5E0uAdjyKhhykq+uBeySi9qVCfSAB61HRBQ8RFJpRs6vALiZHMUnNpYO0Ujn+jPkJJnVfbTBNeqfFQB8YqP56H8VJqBKcuHcWsQuuXIOyUX1sN8MnPJKlnOwWS2SIScx0hkcvV3mXUzN0HcSAuBoNMBYZxsADittVXcT/XcPKE/PltqHowkTYLcMkOMoml52+wr9jnIZAJZ8XjYGe0vaUDSdsBxnulsqrUDRdMLReNHg8tYhOAs2M2HdQiSVBqChprpI7/9q5JPYKv3OfxL1n52ATYYBAAAAAElFTkSuQmCC"},{"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],[2.31953818544,6.55745092536]],[[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],[1.69563043958,6.25076170066]]],"best":true},{"id":"Bing","name":"Bing aerial imagery","type":"bing","template":"http://www.bing.com/maps/","scaleExtent":[0,22],"default":true,"description":"Satellite and aerial imagery.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAGsklEQVR4Xu2aa2wUZRSG393Z3VKhW0AjQgvhjhRMxVoFSkTSVhJEGqUkECkXQSyoiBCJicYYo+GPiAS1MQREMI2GhGI0UQilJJSCFcWqoDYol0ChEG6lLdu9et5vu01ZWpg0nZ3dMM9msrAz03SenHO+c76tDe+tDMHittijP7C4FUuSDixJOrAk6cCSpANLkg4sSTqwJOnAkqQDS5IOLEk6MEySzWaDLfrDBMUwSaFAgKag2e0JL8sQSYyi+1PcSlSguQmhUFB9bpfPeSSaNEMkiRWsHP8kKua/jFdycjHA3RsI+BH0eeXwKYmUlSjYDNlPEkmbC+ZgYWa2+u81zw3sO/kvvvrzF1SfOYXTVy6pa+Byhd/jHGMiSfAx1YJB+OVI7ZGMggfHYnvhfFQteg2fF8zGQ2kDYfP7kQjJZ5gkplSkaDNWghIxAalNaSmpWPLIBOQNGYWQ3we7/S6W1B5qYA3SbHYlyxcMwCOCEoWYSGoPZTntWkIV7phLSkQsSTqwJOnAkqQD0yWxfMd7CTddkp8dt6x0Dlnx4rWxNF2S25Wkmkp/03U1CLOXirdtFtMkUQSH3mF97sXXsxagKDsHfZJ7IuBpRkiG4JCMM21du8k9lWmSFPLwJ69eRlb/dGx9di6qZa77UoTljhiNlKQeSlbgRrMSZmYDapqkEGuRw4krDdew/qf96rPhfe/DvMxs7JlbjCNLVuH9/GcwZdRY9JSU9DU1hLdZEO7aY7kvZZokhRKlYfeJWpxvbFBzHXcNyDAR9takPOwtWordz7+ENU/PwmODhqqoCu9LeZVoh6SjZnCEmS7JJVFSW3caFSePh6Oj9XkpgML4PnHgYLyZk4vyomIcfnEVVoq8Ef0GwOlwwN/ciIAIMxJzJaE17ewObPqtGiF5cXUjLNaMElrjvhS3WXqJ0KwB6VibPwPHildjR+ECLMvJQ8YD6YamnumSmGJwOlFx4jhqzteJjFBYXCt8eK5wlEeJPMd7KHD6yAx8Om0m9kiEPTl4ONDiUdd2N93/E7sAo4Y1ZrNEE+sL95vai2q7jq/Wok0YYR6/H/17udGvZ4oYDxgSUfEhSaWcHduP1eD3+jq4NEdbb8Q0u1VXGEYNIyqykWfUgBMXktR6JkX4vCzzeVs/w+Lvv8Ef9efUOdWB33T1rYTbgTtd1XXiQpJCokESCRebGrGpuhKPblqHeTtLsfu/f3CZDSUvib4nRsSPJFCCrG7SYDqTkuGVxnFb1V68XfEDmlubyI7qVCyIK0msMSzGPk8T+qWkYt3MItV9p7tT1fm7bixpT2TM4JyWpGkonjAFh15YjhWPT4abM1z0DVGoNsJATJWkpnx+zSTpxGN6xsMon7cUJdMKMbh3X/XwfHUWPzzPIyzZuEcx7iffAdUcBgLwttxARv80lMr0XzZ7EXIGDlHLfuThO1u1mJY875LI+1nGmqMX6lRTakRQmSbpmteDVGkA1zxVgIMLX8WcseNUz0NBFNhR/Yl8E0xYv7jNsvzHMkzasgFH68/C5nSp+7sbUyRx9JgzZhwqFq9Qg6tbVrO2h+8kbfjw1EZ5LdJlf1hVgclbPsGGyj3w+qXTdjCKDAgjmCSJo8fUYaMwTib5yKTfUeQQPnYkush3tUcxYfN6vCERdPrqJTiS71G1zShBxBRJhAU5Mqh2tD3Lh2bEqQFXBLHuPLf9C8wo3YgjZ0/B5nLBLtGjJEff3M0YJimyMnUGC3Jn0cOiHF75bLggHfjru3Yif2sJymoOS1o5VO2J7AbEAsMkce+HIu4kqz3qWjlYlNlllxyuQtbGtfj4QLkq9EwtLl9GplZHdLsklTryEDv+qkF903U4tfD3abdLi/b9Du9n3cnbVoJl35bizNUrsLt6wGbXbvszjMSQPwdUc5b0QGnSEK6eOAXzM7ORqjpnRsHN4wVTK7JRduxiPd7dtwtlf9fA7/NCEznUEuvIicYQSYTRE+Iej9+H7EFDsXpSLgpHZ6pz0bLONTZgQ/V+OSrR2NwIOFzQtPAcFw8YJomovoYNYksL/4GpIzLwzhP5mChdNQnK0r7x10P46OA+1J47CyQlqesZOYb9Ul3AUEkRmE5B1hOvV4IkCYuzxmPGyDH4oLIcB07Ugr+Gw8Vu2fzU6oiYSCKRblmlEP9eku+aQ+1I8vNYLeddodtXt86gAkYKvyKySzRp7JRlICXxLIjETFJ7KIURFY+p1RGmSEo0LEk6sCTpwJKkA0uSDixJOrAk6cCSpANLkg4sSTqwJOnAkqQDS5IOLEk6sCTp4H8Lf75Du1VW7QAAAABJRU5ErkJggiAgICAgICAgICAgICAgICAgICAgICAg"},{"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","endDate":"2013-06-01T00:00:00.000Z","startDate":"2009-01-01T00:00:00.000Z","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":"lu.geoportail.opendata.cadastre","name":"Cadastre geoportail.lu","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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","endDate":"2015-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","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","description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 12cm ground sample distance"},{"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","endDate":"2016-01-01T00:00:00.000Z","startDate":"2015-01-01T00:00:00.000Z","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,"description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 8cm ground sample distance"},{"id":"CRAIG-Auvergne-2013","name":"CRAIG - Auvergne 2013 - 25 cm","type":"tms","template":"http://tiles.craig.fr/osm/tms/1.0.0/ortho_2013/webmercator/{zoom-1}/{x}/{-y}.jpeg","polygon":[[[2.9401192,44.6338837],[2.9971896,44.633931],[2.9971676,44.6473385],[3.0159744,44.6473541],[3.0159305,44.6741168],[3.0349486,44.6741326],[3.0349036,44.7015216],[3.0536338,44.7015371],[3.0535675,44.7418954],[3.0723301,44.741911],[3.0722196,44.8091687],[3.0921583,44.8091852],[3.092137,44.8221252],[3.1301398,44.8221567],[3.1300495,44.8770722],[3.1485587,44.8770875],[3.1485807,44.8636964],[3.1682313,44.8637126],[3.1682538,44.8500261],[3.2064,44.8500576],[3.2063789,44.8628393],[3.2439492,44.8628704],[3.2439263,44.8767893],[3.2631452,44.8768052],[3.2630782,44.9175197],[3.3200437,44.9175667],[3.3200227,44.9303336],[3.3390815,44.9303493],[3.3390586,44.9441978],[3.3769989,44.9442292],[3.3770218,44.9302879],[3.396031,44.9303036],[3.39612,44.8762713],[3.4148252,44.8762867],[3.4148923,44.8355255],[3.4333371,44.8355408],[3.4333819,44.8082784],[3.4525549,44.8082943],[3.4525774,44.7946344],[3.5089262,44.7946811],[3.508904,44.8081469],[3.604265,44.8082258],[3.6042213,44.8348239],[3.6236136,44.83484],[3.6235695,44.8616583],[3.6424823,44.8616739],[3.642549,44.821102],[3.6610055,44.8211172],[3.6610275,44.8077696],[3.6992999,44.8078013],[3.6992782,44.820994],[3.7361139,44.8210245],[3.7361819,44.7797075],[3.7751058,44.7797397],[3.775151,44.7522344],[3.8118352,44.7522648],[3.8118567,44.7392021],[3.8311822,44.7392181],[3.8312061,44.7246766],[3.887824,44.7247235],[3.8878019,44.7381833],[3.925626,44.7382146],[3.9256039,44.7516682],[3.9454097,44.7516846],[3.9453656,44.7784691],[3.9643737,44.7784848],[3.9643516,44.7919273],[4.0033183,44.7919596],[4.0032964,44.8052575],[4.0216937,44.8052727],[4.0216718,44.8185687],[4.0596515,44.8186001],[4.0596082,44.8449216],[4.0798132,44.8449383],[4.0797928,44.8573502],[4.173882,44.857428],[4.1738604,44.8705468],[4.1932576,44.8705628],[4.193235,44.8842744],[4.2140385,44.8842916],[4.2139961,44.9100242],[4.2324138,44.9100394],[4.2323689,44.9373093],[4.2715486,44.9373416],[4.2715273,44.9502971],[4.3288672,44.9503445],[4.3287793,45.0036659],[4.3489259,45.0036825],[4.3489038,45.0170656],[4.4060793,45.0171127],[4.4059904,45.0710024],[4.3884707,45.0709879],[4.3884482,45.0845976],[4.407943,45.0846137],[4.4079231,45.09663],[4.4843608,45.0966929],[4.4842941,45.1370472],[4.4663631,45.1370324],[4.4663413,45.1502035],[4.4864469,45.15022],[4.4864022,45.1772415],[4.5065524,45.177258],[4.5064402,45.2450058],[4.4881342,45.2449908],[4.4881106,45.2592077],[4.4698588,45.2591927],[4.469836,45.2729835],[4.4508849,45.2729679],[4.4508626,45.2864203],[4.3936753,45.2863733],[4.3936303,45.3135182],[4.3750893,45.3135029],[4.3750662,45.3274054],[4.3950734,45.3274218],[4.3950283,45.3545849],[4.3767871,45.35457],[4.3767639,45.3685486],[4.3576564,45.3685329],[4.3576335,45.3823359],[4.2814576,45.3822734],[4.2814334,45.3968834],[4.2444556,45.3968531],[4.2444325,45.4107893],[4.1481178,45.4107104],[4.1481388,45.3980659],[4.1291913,45.3980504],[4.1292145,45.3840899],[4.0902138,45.3840579],[4.0902351,45.3712093],[4.0135507,45.3711464],[4.0135259,45.3860975],[3.9170932,45.3860185],[3.9170704,45.3997355],[3.9375703,45.3997523],[3.9375481,45.4131142],[3.975277,45.4131451],[3.9752552,45.4262061],[3.9953725,45.4262226],[3.9956999,45.5209568],[3.9777821,45.5209421],[3.977693,45.5743873],[3.9581755,45.5743714],[3.9581522,45.5883658],[3.9396019,45.5883506],[3.9395781,45.6026212],[3.9202279,45.6026054],[3.9202048,45.6164603],[3.8818916,45.616429],[3.8818468,45.643276],[3.8441329,45.6432453],[3.8441098,45.6570896],[3.8261689,45.657075],[3.8261241,45.6838865],[3.8072175,45.6838711],[3.8071277,45.7375802],[3.7882101,45.7375648],[3.7881863,45.7517966],[3.7688482,45.7517809],[3.7688028,45.7789651],[3.750719,45.7789504],[3.7505822,45.8606554],[3.7696692,45.8606709],[3.7695793,45.914333],[3.751661,45.9143185],[3.7516379,45.9280879],[3.7328974,45.9280727],[3.7328527,45.9547155],[3.8101795,45.9547782],[3.8101569,45.9682278],[3.8495994,45.9682598],[3.8495098,46.0216192],[3.8318849,46.0216049],[3.8317936,46.0759058],[3.8505037,46.0759209],[3.8504583,46.1029545],[3.8324727,46.10294],[3.8323353,46.1845598],[3.8142194,46.1845452],[3.8141522,46.2244234],[3.8336864,46.2244392],[3.8336634,46.2381001],[3.8528929,46.2381156],[3.8528703,46.2514729],[3.8931424,46.2515054],[3.8931205,46.2644677],[3.9130562,46.2644838],[3.9130335,46.2779317],[3.9518926,46.2779631],[3.9518709,46.2908227],[3.971523,46.2908386],[3.9715012,46.3036947],[4.0105021,46.3037261],[4.0104784,46.3177638],[4.0298278,46.3177794],[4.029783,46.3442827],[4.0116018,46.344268],[4.0114647,46.4253437],[4.031532,46.4253598],[4.0314635,46.4657978],[4.0132435,46.4657832],[4.0132204,46.479378],[3.9943703,46.4793629],[3.9943461,46.4936113],[3.9745971,46.4935955],[3.9745735,46.5075278],[3.8775423,46.5074499],[3.8774959,46.5347758],[3.8583577,46.5347605],[3.8583347,46.5483156],[3.8186897,46.5482838],[3.8187114,46.5355316],[3.7992386,46.535516],[3.7992156,46.5490706],[3.7610377,46.5490399],[3.7609226,46.6168059],[3.7423295,46.616791],[3.7422834,46.6439624],[3.7228558,46.6439468],[3.7228098,46.6710357],[3.7038706,46.6710206],[3.7038474,46.6846709],[3.6841096,46.6846551],[3.6840631,46.711998],[3.6648359,46.7119826],[3.6647898,46.7390375],[3.6457623,46.7390222],[3.6457158,46.7663375],[3.6257542,46.7663216],[3.6257314,46.7797093],[3.5672301,46.7796626],[3.5672528,46.7663082],[3.5471462,46.7662922],[3.5471922,46.7392824],[3.5271621,46.7392664],[3.5272308,46.6988967],[3.4877399,46.6988651],[3.4877618,46.685943],[3.4679636,46.6859272],[3.4679407,46.6994059],[3.4679179,46.7127907],[3.4486497,46.7127753],[3.4486258,46.7267878],[3.350433,46.7267092],[3.3504786,46.6999004],[3.3303913,46.6998843],[3.3303448,46.7271984],[3.2327174,46.7271203],[3.2327406,46.7135148],[3.2129042,46.7134989],[3.212927,46.7001302],[3.1735446,46.7000987],[3.173498,46.7275094],[3.1541227,46.7274939],[3.1541002,46.7407271],[3.1147772,46.7406957],[3.114754,46.7542756],[3.0753432,46.7542441],[3.0752971,46.7813548],[3.05597,46.7813394],[3.055924,46.8083069],[2.99704,46.8082598],[2.9970166,46.8219593],[2.9379443,46.8219121],[2.9379675,46.8082604],[2.8986634,46.808229],[2.8986872,46.7942392],[2.878991,46.7942234],[2.8790134,46.7810427],[2.8594188,46.781027],[2.8594415,46.7677056],[2.8400446,46.7676901],[2.8400671,46.754466],[2.7414032,46.7543871],[2.741382,46.7668245],[2.7023351,46.7667932],[2.7023571,46.7538869],[2.6826621,46.7538711],[2.6826849,46.7404752],[2.6634875,46.7404599],[2.6635123,46.7258966],[2.6434164,46.7258805],[2.6434382,46.7130938],[2.6241432,46.7130784],[2.6241658,46.6998093],[2.6039699,46.6997931],[2.6039936,46.6858433],[2.5651245,46.6858122],[2.5651469,46.6726126],[2.5459278,46.6725972],[2.5459966,46.6321534],[2.5659222,46.6321694],[2.565946,46.6181104],[2.5456397,46.6180941],[2.5456862,46.5907192],[2.5664225,46.5907358],[2.5664449,46.5775417],[2.5854963,46.577557],[2.5855181,46.5647199],[2.5661318,46.5647044],[2.5661557,46.5506246],[2.468279,46.5505461],[2.4683039,46.5358205],[2.3321246,46.5357112],[2.3321701,46.5088566],[2.3126474,46.5088409],[2.3126703,46.4953444],[2.2928767,46.4953285],[2.2928996,46.4818182],[2.2748687,46.4818037],[2.2749151,46.4544154],[2.2553921,46.4543997],[2.255529,46.3734888],[2.275948,46.3735052],[2.276037,46.3208741],[2.3145615,46.3209052],[2.3145849,46.3070421],[2.3537075,46.3070737],[2.3537313,46.2929669],[2.3938428,46.2929992],[2.3938862,46.2672854],[2.4515727,46.267332],[2.451596,46.2534921],[2.4709353,46.2535077],[2.4709807,46.2265552],[2.4915062,46.2265718],[2.4915521,46.199329],[2.5108806,46.1993446],[2.5109254,46.1727799],[2.5311728,46.1727963],[2.5313772,46.051352],[2.5516349,46.0513684],[2.5516577,46.0377665],[2.5705635,46.0377818],[2.5706774,45.9699434],[2.5514356,45.9699278],[2.551458,45.9566151],[2.5322621,45.9565995],[2.5322849,45.9430066],[2.5130653,45.942991],[2.513134,45.9020279],[2.4749412,45.9019969],[2.4749633,45.8888235],[2.4361947,45.888792],[2.4362172,45.8753288],[2.417209,45.8753133],[2.4172548,45.8479368],[2.3784736,45.8479053],[2.378497,45.8339746],[2.3595157,45.8339592],[2.3595606,45.8070849],[2.3787254,45.8071005],[2.3787481,45.7935783],[2.3986981,45.7935945],[2.3987203,45.7803477],[2.4182486,45.7803636],[2.4183161,45.7400007],[2.4572171,45.7400324],[2.4572394,45.7266956],[2.4758919,45.7267107],[2.4759144,45.7132391],[2.49533,45.7132549],[2.4954204,45.6591268],[2.4576942,45.659096],[2.4577622,45.618343],[2.4391188,45.6183278],[2.4391866,45.5776619],[2.4585044,45.5776777],[2.4585496,45.5505348],[2.4780887,45.5505508],[2.4781108,45.5372464],[2.4975506,45.5372623],[2.4975949,45.5106757],[2.4785536,45.5106601],[2.4786444,45.4561337],[2.4597798,45.4561183],[2.4598701,45.401757],[2.4224876,45.4017264],[2.4224651,45.4152816],[2.4023154,45.4152651],[2.4022929,45.4288193],[2.3256006,45.4287565],[2.3256684,45.3879609],[2.3456182,45.3879773],[2.3456629,45.3611091],[2.326256,45.3610932],[2.326279,45.3472146],[2.3073819,45.3471991],[2.3074045,45.3335972],[2.2881095,45.3335813],[2.2881307,45.3208191],[2.2696332,45.3208039],[2.2696574,45.306212],[2.2506602,45.3061964],[2.2506828,45.2925147],[2.2316866,45.2924992],[2.2317086,45.2792355],[2.2130009,45.2792202],[2.213046,45.2520355],[2.1937387,45.2520197],[2.1937617,45.2381134],[2.1756091,45.2380985],[2.1757423,45.1576822],[2.1573543,45.157667],[2.1574448,45.1029478],[2.1202408,45.1029172],[2.1202629,45.0895468],[2.1006669,45.0895306],[2.1006902,45.0754441],[2.0824591,45.0754291],[2.082548,45.0215961],[2.1025534,45.0216126],[2.1025982,44.994453],[2.0457406,44.9944061],[2.0458508,44.9275321],[2.0657794,44.9275486],[2.0658912,44.8596881],[2.0856964,44.8597044],[2.0857193,44.8458126],[2.1055593,44.8458291],[2.1056029,44.8193264],[2.124743,44.8193422],[2.1247657,44.805512],[2.1435067,44.8055275],[2.143551,44.778597],[2.1256091,44.7785822],[2.1256984,44.7242739],[2.1066459,44.7242581],[2.1067116,44.6842263],[2.1263414,44.6842426],[2.1263635,44.670735],[2.14598,44.6707513],[2.146069,44.6164441],[2.1839622,44.6164756],[2.183983,44.6037819],[2.2404173,44.6038288],[2.2403728,44.6309515],[2.25948,44.6309674],[2.2594571,44.644934],[2.316678,44.6449815],[2.3167011,44.6308801],[2.3361516,44.6308963],[2.3361734,44.6175824],[2.3724238,44.6176125],[2.3724009,44.6315823],[2.4110495,44.6316144],[2.4110701,44.6190741],[2.4492173,44.6191058],[2.4491956,44.6323197],[2.5048575,44.6323659],[2.5048126,44.6597555],[2.5246119,44.6597719],[2.524567,44.6871739],[2.5422544,44.6871886],[2.5422313,44.70122],[2.5807101,44.701252],[2.5805999,44.7683374],[2.61769,44.7683681],[2.6176235,44.808838],[2.6367564,44.8088539],[2.6366899,44.8492948],[2.6733105,44.8493251],[2.6732888,44.8625164],[2.6933766,44.862533],[2.6933323,44.8894303],[2.7305201,44.8894611],[2.7304757,44.9164461],[2.7499202,44.9164622],[2.7500519,44.8364688],[2.8073346,44.8365162],[2.8073139,44.8491017],[2.8263796,44.8491175],[2.8264007,44.8362845],[2.8457039,44.8363004],[2.8457707,44.7957107],[2.8642166,44.795726],[2.8642611,44.7686452],[2.8839885,44.7686615],[2.8840323,44.7419697],[2.9020315,44.7419846],[2.9021426,44.6743192],[2.9219777,44.6743357],[2.9220221,44.6472986],[2.9400972,44.6473136],[2.9401192,44.6338837]]],"terms_url":"http://wiki.openstreetmap.org/wiki/WikiProject_France/CRAIG","terms_text":"Orthophotographie CRAIG/Sintegra/IGN 2013"},{"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],[15.0063684,49.0177392]]],"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],[15.0063684,49.0177392]]],"terms_url":"http://poloha.net/"},{"id":"Duna_2013","name":"Danube flood orthophoto 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","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]]],"terms_url":"https://firstmap.delaware.gov/arcgis/rest/services/DE_Imagery/DE_Imagery_2012/ImageServer","terms_text":"Digital Aerial Solutions, LLC","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."},{"id":"DigitalGlobe-Premium","name":"DigitalGlobe Premium Imagery","type":"tms","template":"https://{switch:a,b,c}.tiles.mapbox.com/v4/digitalglobe.316c9a2e/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqM293YnJ5MTAwajIzMnF0bmV4dnV1MW4ifQ.psvzzOez33BOH8xmRiJZWg","scaleExtent":[0,19],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","default":true,"description":"Premium DigitalGlobe satellite imagery.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMQAAADECAYAAADApo5rAAAgAElEQVR4nMy9a7Bl2VEm9uU5595bt6puvd9dVa1+6k3rgRCSQLKMEDCBAHsEGptAGE948Bgz88Nhw0w4bBzjmBl7HDE2EzM4PGZgAIMNNkYEDKDBIARIAoQeLSG1uumu7uqq7nq/bt1b9738Y6/M/DL32vdWYzw6u6PrnLP2Wrkyc2V+meux95WFd31fAQR6FdRfRYuF7ujvAhSpdQsgUusLSikQ6e6hfkcpKOJ9AIBo/VBaINRfqd8jd17Lf8HqgspCy8pm6K0Km4pNCYUqimQukHrs/mn1kcuoi979QNsGo02rRNVXjTGf3e9ePRoj2bZe/Oz1a+0j41omLR53+vwqyzBqDoR9casohe6WTmrroPiHVKcA3BkgYgMsXN9csXT3itBNN+lKDp37CUSZLahKIPrGp1FGIQYLeaBIdWhSQnGmjIoqXukYYIQr4IoXCfVPl8oQnaEow/qBUoZl0KZhHKoM3QAL3S9WjwGro+P1CtHLn8a7lhMfYgXFxqtU+mx83m0JKpsWGUadSZCFEdNqHGrodk+otoj9dmSQrhK5paKx+5WQkmpLikjqG2agQrwpkmQEQHHe2AZL11c22FJxxepKsahVTCvFBpadjEe4pHtqyPpbqtu5casuitdXPs2r6XNABuOwqB7EeFMDLUX5T9G4Wg3zqarOZd0n91VcBi1HB2gWu4WjqttXMGiZPhlGqKFGUFCKCyAiHpoCDyV0CL1vdat5mGEWQ0o1GTKrDvOLO5wyZ3XFfN946OxCjK7dFa/p5WpYETn0rnQj6b/pm1LreCjkky6Dyizqt8Y3NJDaIIoAUgqhktQ2xXkWgXDvso0M4nX0vusZNeIqx8S/RnCAxpiN1cdd6Qn15WMSy9lQAv8SywKETJkMk5hjVRhns0ioChLUWfLymJu5ZCWTMWQWiFDmKNRAnaT+o4KZaTBzAsCpIJp48Win6Z71UarlKiB4lLDhU4dlRDNnrTWlmMyayypN0xWlj2Te1BOXlV55loGCB1AEnnGqx1XaharTgMd8Xex3Yd2bIgsNIkd3Zlvp+fxS4dZl6I/rNMkwcu+IA9NLkY2MG4Xxqy0FYaA6BZFwxjQRkxgzDHlpzAOuEGOOIqlOjxUx5HUfLarnwEPEMUIym8go0zQIhdsb/Ft/wTlrbsCmnl2CuShlWIYuChVjS5iizduU7443Q0YNYdXZu2o+mKZ7YVmE+CpG3/otfSlQXIZSaXCEmDYZRoZVRf9hB+w80OYTNFg296Q2yrCFd2png671henVT8rVJd9TmpQWmYqkjbU6Go5Z8b4k/LKQa23E5dGvqkDTDzwkB9rcR5WNUjPWSXFzCXqSUjq5t5FB5xYEZZZmaWTLE0udbzEGampDawrk28XLRdOSKoP4yo5Uw7ZITuUC1R8h+BTKYKtMKkkpahQgb4rLjm4QnYGqpxvcWhsaPpvEqNc7dGqELKpFSih4IspCRkT2ZVZH1IhIpVBkMqJdiFXa6mxhibhEgCqmJ5gzMYqXGgVsUqd9WB4pKFJCVGFJTIaqVNVZUwYwcKH+Fr8tcOmMp84xi8lF4FV1qfM+BzafT6LWs/FnHmiQOHXuutE2KoMvVkyTDKMSDN4N33cB1IPcpW0gCQn4N4qia/XsoqHKL7M581oPaW4c7mgWlUqxfsycKFTHeYaVOu8WSqSmZVrbhikglcGOMSz24askhfrs2nB+avMY0g3zWSyOaAPPi/uxkgyFFV89t6gMjmqdsYlYWqxjY3pQjy/eq42H9ekg5cjqJQrVtjonJcmPYEM2J5syGUYRo/qmFASAV+N1cSgSFL4PsrPCTcElTFZv6GpXCDpmbtFhlIYqMfCMzoEUDTxgEYxBEUNqyiaOOEazGMq7IzJzTK/v0DbxE6mG4sut+VI0DMg6IIONiVYW3aPxSMLqdYMszrJryhkm3hQ9LdoTYLJh6Vexwff83xYTGFegwDBdMozisPiASs9SYzWhQVPyERWJxwaDlnblcsDnC7nfZI0c/qIRuw8VQ66WECHOOF3h+s4k79h0BbTsB5UzqjnL7OimDFbdpVUM5mBIhhYIUG91jNjJ8yyk2DiE4RbltY+ongsGwRAm10a+OOFk5NMqwygyuY0TmIwlerkEetYDCxrNqLImbQQw9Gv3Hipq2NXvITwCKGqw3LqDXRRDsk4IM2jaLbfAbJM6Rxb3Tv9lfIU7ceIehyajq0vOSdiQDApMEXQKdFM0c6a0HECkjkMySbMXDvV8n1d6SC8+cTK9NuNgBbEyhTKMAAR0yrt5bOh+fqREaIeGP0Vm6Q94ECcJV0os5VyzytIJ5hl//xSU/6tteMXfB6nUsOwrRVJ14ImMt2N9eE+KVjqgJEN1Nkc1501qOqD27BtuQm2K67UgGlWSgcvVSHgu6I7E+XgloTNKINSzjnuLJUzH2WmOMKcKTRkqSEyhDJPKghOtlX0y7MR0ct1tu9OGCC8poMTJqtIA7ECf1hfycFUSlBNykpBiwI1KlIdKz42sJnSlqkngxk8TNRRXjq4C2dyuis9Xgdkv2NhNbwWkbFqxA+lSvF8bDLYLEK/meEMyIPZJ48TpikCoHf2GL5Z0KYeYg3fD6vf4CnagSGv5ry5FU59hMk1gS4qdFhkmmiJ4B13rEoh42NKczp0BPriiNWB1IWREDSYy/dI1NCq+XOdKcxRxLWuZGxn3VZXFDieaNhVXoonEjuIDqW3jwIRRNd2oUUBTA9aMpD6MHsU06q+r05ehN80Lk7ioK0/FGJ2ZHnenoMjjg6BzIZ2bBnjcuD7zZW3b0eWrLcOo1I51EIq4Y5TCDWH/x3CoaFaoAoECexYZta1G8ESp1ChSnBaZMBSS2U+L1SeH5rbkqFFvDWcoZJwqOzm+NstoZgfPDNW5K4kIWmnyGR2PBLX/kvodkqHE76IRmnL5YCwl9uX0qQ316X0orOvvalwl0Tb5uu/OB3oOzuM0TTJMzJDrgHW8q3cxQXY8CUKyxxeUcFjPxjVHhhbipggTCEgXxzR6ZMTkf912I6VSFcHHVTzb0xUjR6EYJt1xWmkjy6e5a754taSjI2ZF8QiN1yWw68sgPAg+dlL54fSMQ2Bh/iTYh6vcEIpQXulqDKzMBTWpjJnxMA5VR0L1p0SGUVjXr0ZJm8gKvh1fZNwaGbRO1IdE5uBe3ZtwgYRtas/BQFR1hOjR6xEmyZkOO5A5jRq4Cql1FdmpXx8TdT93Q04PRPlKl9HT9Eg6hMoRx/pv6KKX+lX5ewsTia9sK1wQ+lJ65rwNGRRxVX5C8yBDQwdBNp0fTZEMI5+EOsfOrA5AqeWOZiV80vhz7s36qRZVQA4n1huCYyK3C/rkc3UdTa5j6V9r74F0o6mWsiyqwNin7266VzqPHDqJrvhCxaCfD5T3mjRAtvCXCmIZg3oT72wYLcsDbPyCEWZeqzUWBSIzAGfE7K3Rl+tNpk6GkU4EAfXQevCKiOlqfqE1ehWMHSmuDFX9FAqKhdA2y6TGWb3bEKCzL6vTob/fK+m3nXy1eVB0MQdyGgE9MUmIzwos6bvzTu21TOrxNfOHfqQyPgY81lPVTqghGdhYfKmbeVZhQYPQl6krCK1DX7pnEOYEKqNUYpryhlUdIXouT9z0nS4ZRqUaQuibBSNezMq1I3o8zQzMmGX0zIwkQzUjU8VGYYLnp/xMuB/Wv02WJbZlhWnqh9SWUsJOLHcudlTSq7djnjhFrPcTplg9k0sSbcg2MqheiKSlLamepEmnokkYJ74dx9ZWdUrdrymBUlsfPQajjUyjDCPPodnAkbxYx6pGEsVSRgcgGD0vKVrHAlrGdJwtBou8LR8PSjgjOnFFdR4x46WmVR/eXidofOSsOMlqs+ogQn11ii1Eu1iY8s/urJOOJaVt6lyVX2G+jF4ylDTRHpTBQ4mnGyZ/to40nhV4er6pdAmEijpy/S2apjqxRneJttlmNvLpkmGkDGjeTOAXPiv29dmixE/YWC3C6OS0sxZFWkZNLevSbw6vsO9k2jBjJmczUOI0g0jYRDilN0pSKq8qktLU1a9uIsby1whEOpGKgJL5B3yiXWhlSu/RDwcEFd3ptGTwianSIR6pbdz3MYoISQrpP0d0j4wlTn5LvMdAp+mvH8UGRcw4vtMiw0jqAEk1om7JVIeluoE2AJ1R4vFmcOPwXu8xoheNHooCInasVxT1a8QIKzcmoLj1JxTwaEVr/6QY0jvpz4TrnBLFxoAn1CYD1K4L0Sr0DEXplmNpYqf9AtJ41qLmtpoOEK8UfJsyFK5Ao2uRjuVXsGJoSemnRd00fnEJXaJRMqrniybL4b6O+xTKMPKQxSZvFkffNa0q4GdfC+gTBNrFBzEwD0UNr1MfCqtlvoPMwUIdSesrWxpZzEGoXzVcR5Dq6IRaira2Np4XDkpdkoWQPLobXWz5Lk7soyOaMwt9NyeJ0ckjriZeMihDb9OQZeD5DhTcQDpNR28YKUrUUbhYPYy8yjvivaa3aLsplGESYAjKIFm1OUUnQVe9cwodYAhoj6gyKR2tOJjuqRL6Ux6Ll9gEUoKee5uAhMwdAhNNZY77LtqONeSbakX7oPDMRyvCBqOpwXWoBh/2F1QXLR0oLeXBb7j2ZUgGBzGmxX1wvZ4e69h0m1yk/WoCvGcUj6TY4JEKq7FqyiiIdYmG/RYnMS0y+MZcHYnOMWtoV19wCHAES14WpzbulTx54V1dUyDrM+XGcYUGFiqE7nsIlfCKF4cRNC5R9dc6XT8BqTMf1Fblstq0mlHUEYKiCVqKn6lFGPhKl6KK7CBD1FMCNdJ/0AdTEJcb7MBE3iISAZeWR4rKfyppoHnxwqmTYWTVhb1PjZWbDoyLtVXGggc5AylF4HsepFibEtpUqKTyaJgx4YYjTXXcODllXXnMZBeNS50g1GLmqW0htri/KkOvWYrMgTnlIoFPlqEHwaaugjQE/bHbLo3I/Aw5JBuojk+jGrfvrUROmQwjHizDLhGfqWcmaweWsqWOdKy7ex4JIrPRadz2KCIAPYVsf5G3MT27GySgPF7MsIMzs1wKFiyPokgH9dVXnYe0xeQfNtGMqBd0NSB6lsFCTykRmgldUSftnlmW2FblilbbY9159Dp5JznS074rR5YmUkpVpk+GiaU7EpevSs3hLa9VJvUbAajnA95JXiLzTS06chuciaAQ/bmHy196xmQQbLLAJruJbeO3lQbZ1xKL2JDtd2Y5kbJ8Wagwy2aWQQ7UAoPET4gOpXWT6SQttpJnpaOG1Uo7LK2h/lTHNvbUyLEzGCA4onPfUyLDSOoSoR67tYsMWgBbetXVFHVIB8pmTEqCed+mo0rY7ZcMT6lm+dWhk8N1VZIismFltAi3KZplvnPkUpmDszjS9M7daEN1RpIxfOf+e/f7MvSuHs8llvMKFw8EA1RJ9cN9GgyVOfdpPJMiVU9KPwHwtMhgz1T31t8pl+UVraIELM1wx+z6VCeKhtmtODkjfsbJETLn3bWUFBIjFkcBTifiUpySLCa8v7GyrixVBTt6kFDZESyVjKtQOsiuq+Kf8HEYBI5kG8YXO31DBq4fELLUPRXTiwth53rI2YbAoYTvRN/KxAGtqMwtRyAa+j28WnI6ZBgVtXjx5c2wTAp3LIsQqN5tRwzMghEkpN8MEF0jPz3rfYl3wiRp8qU2oqtL5hPVUPRepm6IzeG3OqIeAbC+WAoybr5v+xXhUVoHHMeN6Jw5jQS19Rk5bE4SJtJZBgJEPUtmTiQqG92nurrzHiJrMOaOZ4HLEPZKbFGjFqlta66vv3WsGCjD9+mSYeSTwaLwH84A+WDwD/UuX/ktwYI8ghiCZ0RzK3aDtifwJTJODNguehXIJ1pQTzFZbU+lKkaRwXfOWTAyTFYc8lyoIQPTUTLkpMYvXyWVKaspP95WBtMDkxG3RENCEsxoIfKl/h1AMSM98x/R3dpQ2uLgEA20ycOUyDCyAGHeFVFL2TdWFJqqE+QdVN9ijx3ZikKt23qAhyJiaktHd/VhCiNVopUab4kYrQKECSzT4r7ZUVRxvNLBY9jHD6sfIDAPQBqgFhkLBYMylL7uMkiYHCCDdecKvFi+rf9XfbJT9mQtbjucPzMdTgHDK2amS4aRepTzUpHJA4a3ScR6E3k2mEqH1+/dJwzCqePqSNy8oomFR+Yk8ZatU+h7trQwea7/G29NqwQpNtZTcZx4od3yGD1CXUFPBmG+8tWSgVILNzquS0wGI/BBD/oGnB4ciLrhChoN9bxIGJ6TgcSde9fldMkw4pTDowXgB4zgKJyXswKyqjLEfpqSgsJUcBeiM8bYzq2HvVUFSBAk6TfxY2RKUkQSQYyFDOE9pgJbmd14yM+bFNLFkM+1+OqQdECGnIZZCpn4FlJnKu+fHnUG7IAkMRwWHlywaLBZhbn+gMzTIEO3U615NwoxI2TjbojBZhIqUwjoyV9SoUWb0k1/g/Fk+k3kMDZjGy3XlaPqxxDEoxBm2wWmg6rxcLKUaPX7oAiokUnbSN3crLoXk82PnvQUY8qiY/IiO8rg7VWxcTLeHARKU/LqjOrV5Jfcno7fSywP85xalFIQ02VzafqrLMOoupEnGgXwZa4Y612ubLnsvbWtGkr67OrSQS4A/uggSc1OXK1BI5f7nRtHXNkofhYLdTxsblOYTZMZVNY/8yJNJOrGWnXEh9Iqz1VhFjirEcRz+j6oLoA6DkfXhgzspUX1qTzQ2CnvOvDqXToWDYSNfWjfrvLQQuh/Lub5nQFX8aCu6DpFMozsL3gqkfAjrKJbWaQCtV9CUjZ+ekbb0NStNxpn7Mr2IFLqIxX6zcNjb66wMN8RN8geLHX3I/gUioyRryy+fudTluavqY4PrETHVSStHpSf5WjLoJbFXaR2dDssNBhYcIUkl2IFg4Hpg1GoUFuXwdLWLEPob7pkGPHNXjiPEFsdmB7sIBE6XhxJGWW1zyBZNYieIL3Y6Chb2DmgfTCK+KOb3gcp0pSUFMh6ykiXVNFL5/hSxIOjWS+UpwbSE5d1RKjYkMEm1tq35mbqnKD+C53b0fEgtAzyljrONUo1ZWD0Ntm1P7pX8rJ1ROtpk2FkD1FUVFKj5/r8Q9GeD0VZiOtxxZ+NSyOH0tD+w71i/bqDM2wXBEMEbE7Eodj3NRCNsGXYpIPsIHl+DfCAaQdep3kgL3Tkn81B20YGizShWUJbvc8gwaz0nM2dTp2xy/Wpk2CEhPAlK9SQjOZaDpp23m2KZBjxfQD2HKz2JkW3n+p3YVruOBYAijqIxNQhyZmPJbgTqkEJ2YLuQDf0NbBKUYICB/TdNG7c1xXjI4cYBHmZ5QAbDVQLObMWbyNDqQgc0FJlqIah38NCAUqilx7cIb0rOxne/BxXR7szm7hRanUVbIsnq/6g1XTJMOpNSETozX3xpKuegAVNTIM8OmFS6YQNPFpA79yQLgeUAl6CtajYq6sMdL8La5J9zWQurhUjlTyWvvPgNaMBj7jxTcNT+zGwoDHvGOI+QTfrPeW7lEEZnLYWCoIe2Q1DaPN6hesVgzJLny3a1ojrWCLGp4534I/SYZtcSycDR/Bpk2ESxgHKt1uUljmw5eMS8Lpq5DQhFPUcuuydqBw2mSSFQJtIpuhiP4lPb0+/RFenYpiNEzZHYT5saAQp4tncKIFIEAB9HdpgWIiVrBbYkfH0eK7TSP0Ui9EU9fisFh+zr7qgMTKg0TEjz9WJe++wJhmc/7kEehpOXAZjV5QCjQd59DTJMCoiYW7byeKRQZ9VJV7JoPTgFC2FshakDq4RrrymP5Log0zr7wUWZv12MVRBQT0tqf/3nanniLUPjVy9B5LYUVgfZJUWZun/EL1IUYVpW//0q1R61pWfPA4MDMhg/XC0Cs5OTw1SdM+TyVL1FZ5TKToZJZ6FAIfmd5pHM99NGeKLkCKfUyLDKCjXWQUnS0UZJvn8ZCKi1yeF8F/q7ISqTIV8EMGa3UkIUVkIQ1AVipDY0i3d4whsU3iufHUeHerASXY8sNEqP/5uHpqAE5xTWhnb0shI6MaaSh6QIRkYnWmlIJgd6aEYSOnNrm04GmM4QjoVI03znFrRuuXnalyG5pyMZJ02GUaWtgSOg0UYAkuwXlAuaJybBoSplK6kt3zGvlgrWmsp5CwJPah/NYze3kIpMfIZi65cD6FkyJUvo+0e7H3mNrmfojKgEXXyEqAPSMt2WlfYM+EUTPlVVLVxc3bcWFwGm0sR+DB7irYuX1/XjuTZSULFXptpk6H7+xCS+kj0bE6gPznH3elqGT8LxUbvXbnBJuNS+fgzf7c2vRtEt9WY7D/MIXSwwNEg1u9dxGQ8/kw0Ut/SEmw7GXIdGsTm+Z4Buj1aua6kgh7thm5aHYb7A31+lWWoZ5mk37ZGBAH8fI5ZZAPLCqInZaVIHxE03bJq4nR0ky8YHD9uamhANDV6iNcNPLEMneDhXj7dG1CiFQkSOaMnhFitq6T/h8qH6lhISZ8ptS0DiBhPEmxfp3meSOsWqltiu4DIOUoy31MmQ3d0QyJvHWPwyCC6/+DWoRtpsT4o1A3FLWdMArMS6nCkUOZKoWcwFMBT6BOG2awIlcmQiKIAWilWLmgolsUiffhDV8k5JP0PKqfv/LjooAy9VSd+ei894iqx3HhSEEn+a1rkFIhTVdMjrRJSNhD5o5Q8dCJTJ4O9l8n5rwY5AG9qxGE7nI23MmDg5jI0nKSfTlhksN/FFMe2bO3DBKt3sxmZO290BPA+ksxJrmi09IBLi746nCAsDOx4tdKFIRnIEWn1PVTRFI1XbYykvmAipzyFnnwmskENJStFDdZaBgRucB+/TIkMtlOt8xld+rNXwMONVjuQXF58a96cApRugVdq/IENV0oxzo21sPpVggaNVtGmSfHKz+CAMDz7+ZhCfXTtVG5SnGq4PubqJyi5L4mpHcKXZjpV8g+mNSBDDxjS6HCEiZtaSpfRN3ZvGiL75NU0f7dv1bMZLK8IMRG4AYogczMtMoxCWKY3aWRUir4Ub9qafqClN3XrnY6YO0/xbyWke4qytthjYU7ApDIChzdsZ3Qt9BkmVvREV8vYggLExiIiV+6LB0mNoh0xJNlBAIMBGRgYepfRct7D3kztg3dzDY1zfqD8FC6i6GdddZXSUKrQQQe2ejRlMozoOB2UPR7fHBUKw14spBDEX4WMprpEjym6b/MF91xbbWoZnHKoLAi1oWXgoJjC7ROsULXQTwPS1P87A6AHi7TcJvrUlg09d5SNQiF2SIa8UsLOyZNCs5+E1NQuGG++1Cgk3y6RDwsJjHguQ3x0tzEPnQIZRuAOdFVJq5rHuRdLdf94jJeF8+MYPMvvHXVgpFbjUSOGb7LEpbzUjuobf/W/YDQWYViBDT4k3S+JRsspSR47IsD9CfqTdTMS/p14DDg1IAMqaATVkjHmCWsDcfubioSabIyBFjPMekD/oj5DZOQJ8xTJ4KddOXSIGzpPZEXLKxO8TR5PfLqB8GZNb23fGE1oaQNfFUZKbMzLo0FZe61LqBA2+9AwPpoLwdt2MsRB8zCgfXLo0DQxh4cUYbVAfboketZ8QAbA/o6CAxfP50rsg4U3HZdYbmzpuCVQBAKKN7A4ysZ1mBYZ6zTJMFIi9clmvymehXFOrl4eUD84np8s9MN5yZh6Rk1LaFxHyZvx5a35fl0WOKRE1VF1IzLkO+KEFLOcRm2lDhQMPDHBkdRoFOvbAxohfiBBgKH1sY0MUHQV7wOUOiQdFPhvT1EZhb1/G30RhAmO+H1jg4ytUB1fDSrOByN1iBDTIUN9c5+Ews7+tFMfM7aFkAKZcw6sN3NRAMdin/FZgELAoF+ov14kQZhQRfQv8Tsty4W5S7jvz2Ko0YpGsjTYQRZDsDq49of7GMG0n6QTcqawJKw0WzJA7aXKIFSoxGwxI93TdCQMo9IpJoIpgfzdHFnIAcz4VReK9PDHCUj1maVpkWEU6NUOunuMSuQU6mgl/SZGfQlMgvMIE9I+SupLUVC92FCE+kS6tB4J2clPCmODU4O2uQ7xr8CeQ28IWR09jmqdLDxA0fHYiIvRhB2DMefUtmE+MiCDsk23HBAqoGlBKfZL7SU4GhSX6aEd5V95DYNOjxwnnoQGQcE5bt6hd02LDHVjjislgyPgDVmCxApWR9iYK+2A2J0xhIN5GTIKIy7YPkh5JTbolcHbV74MJeBlIa0D8SuUxjEd0wNN3uH8NnlACgCipwNKiAZhNS5EiG1kqMoJ8z9VPjoDcbDQZ0OKO2HvT/4ouDAKq2YqOIkbe5in8XcGlIDMDW+YIhlGoCsgedfMaOmR8K6tDpojMz8zUYqYUKIMJ4O2VSXusSgWpCMADYdpT+JB6BJJ9xE1V0BFIDdye8DEcSnwwIYb6XBHSaeUAjKSGm/aRp2V+MkyqO96uaJgalDQjU4SwfXI9dCoJ4Gqv9jY9ocZEa2NITm1zdFt2mSYpGbqP7UCISBAE2RRkHSWS56wVkqKnFo/5cCo5YrUliIU9efqjmoc1N7QXdubAYPaWMfejhyOZfDl2u5XRGcfAG/o/bEM7sk6Qq7H2ZkJ9szvwu5ds9g1N4tdszOYnUwwOzPBaCwYjwJGYWNjE+ubm1hb38Dq6jrura1j6d4KFpdWsLG5GfVp6VfUc6k89PRpoOPgIqEdbEGjO/NWaMC0H9ZHGl8CNNNv/Wa0s018lWWYlIryMUWR+uyDBCQNTqGVzUkqNzRBNgWExyWpPdlO76ivsD87j2ZmMejYXMAcgJSl69zCfamm9Cg7O0vlzZ0J/pRfRXDlpXfmiAZHRLBv724cP7wfxw/tx9GD+3Dy6EGcPn4Yxw/tx7FD+3Fo317sX9iN/Xt3Y25mBrMzY0qdgOWVNSzdW8Htu8u4fmsRV27ewYXLN/D8S1dw8coNvHT1Ji5cuY5rNxexubkJc9IG6LCTmj7JgS2iV7KCoAIAACAASURBVB2oYal90bE7T4fpOx/lsYd1qo34imUPMxOvkZd/4zLsfdeHLbiQL8IP70kz7cvOHRA6NTC8TOhRyEj1d6c/RliiQ5PgZirauhKjtixsYQsRaTTKhZDAaK/ao3K6PRoJzp48gtc/cgaPnT2Bhx44jjPHD+P08UM4eeQg9u2ZDwPJ+zosp17haAj9LgW4fnsRL7x8Fc9duIKnnr+IJ595AX/8xWdx685dOOAwaKVPICrS9JH0m9tU2iGlS2qygc3loH45umhGwOVfBRlk4V0fpiBAiGn0C6UN6TGMYLcaUeC5PN8zhKUb7rbGYzA0oK/MjO5wdGo5I3kjNBqG28EZaFAyz+at3Lj7MR6P8ODJI/j6r3kcb3/Do3j07AmcPnYYxw7tw+5dc1V1ET25fxN1B0cZai8iWLq3ipev3sTT51/G7/3pl/Cbn/gczl28Qipgvesw96zYPxuo47UJGJDGK9VseESjfm7t9A3h/w3JIAvv+nBx4s5yvrhZZIGDUGJLo4b06wywuKOqeqhjsvEmYGOgMrqwg7RCzsA48qrU/PwcvvUdb8Jf+cY344nHH8Th/QvYv3c3ZibjQUPOBs9XdoTtIsVQm61ScHtxGecvXcNv/OFn8bO/9nG8ePl6xZN6CM5S4ipUAoy88hbycdYPkCJB/g4Dku4OWViKEHG+Z0qzMSvW5v9fGWqEiA9ihGO2wYu6zpv2QxHO+gopUk1VdAWK65NDo3q9T40d4XT1Slj5QcjOsz31YqUysYwAKVKxtshhxqMR5nfN4uEHjuM73/u1+ND734ljB/djZjLGaCRxIAau7VKkncq0vNVP6/fG5iZeunoTP/l//w5+9tc/jpt3lrC1teUyqYY5MrPOSA0Y1GWqn0Gr9YlS3+aSaIbyRr9AGq+/fBlsDmHi0LyhKLWC6DCcf3VuHUBB7+mAhs2PAaMxupw7Bp5SYBwwulC34bWGVA0gag9swczMBKePH8YTjz2ID37z1+Pf+trXYd+e3YP9b5WC5XurWF5Zw73VNayur2N9fQPrG5vY3Nqq41gwGo0wHo0wOzPB3OwM5udmsXd+Drvn52y1qSVnC8CGHEivT3z+K/iHP/UR/OmXn8Pi0r0eLQMVS1EKJCILoW9SbQI+vhmzhTgm8WgPT3xbGYWCWD+P+MuUQRbe+WENSKFG6LKUupFRzYkDB/OqdTHUKRHP34fK0PiO9r0mOmcmGBG0Ye67tpuZmeDRMyfwjq95HP/Ov/02fN0bHsP83GzPIDc2t3D99iIuXbuFKzdu4/L123j+pat46eoNvHz9Fq7fWsStxSXcuXsPK2vr2CrdxuRcdYQDC3tw7NB+nDh8AK86dRSvOnUUZ44fxgPHD+HBk0dDnzmNGrpa6dWl67fwz3/5d/BL//qTOH/pGspWhTx7e51RjspS8Kv3THNCOuf0Q42jVOMWpjk0NH1Dh1umy2vOwznEX54MXcrkHLgXVqE8ykUUyBGj8SI6kiudVcrGTLQH07eck21ztRyxE0uRIwKNTqK0zWQ8wmNnT+J9b38j3vf2N+IdX/M45mZnOlXWwdjcKjh38TK+8Mx5PPPiJTz74iWcu3gFL16+jsvXb2Nza6sOqLj6ydHDipnyaf2PceroATx65iSeePxBvPV1D+Mtr3kYp44dhCA6wk6rVXnecmfpHn7zDz+Hf/ZLv4Unnz6Pjc1NbDfPy7qJem4vYoTFjWTn3c+G8de+JBuSB+qQ6TCImpb/EmToJtWJ78yurdX2cva2UnwuFFFqO0QLMvLEqVWhWZAhvk28Nf9hMiePHsR3v+/r8a3vfBPe+NhZWyYFgK2tgpev3cQffu4pfPILz+Arz7+E51+6iis3bmNtfQNu3cLCpDSsfrMBasjg4Rbj0Rinjx/C6x4+jfe+7Q34wLvfgpNHD/UcY7srg8zq+gb++IvP4L/957+MP/7in3fzCqAPSjx+5lhWUMXNluogGRxf0yC1tpbNAGbk0QBLpVU31uj1kwTzfyky0KS6VjBeQtyAu0M1dAFjH9WtocvCGjOfoEIVELSZlBK9D70osZ0ftICoNyBdpZEI/uo3vR1/44Pvw+MPnsL+vbut6dZWwWeeOodf/b1P49kXL2EyGWN+bhazMzNY2D2HmZkJNje3sLh8D9duLuLFy9fwzPlLWFpejaGoxWwzYvbLRiLYv7Abj589iR/4zvfiQ+9/Z5jIA20HGUqxNja38PQLL+GH/sFP4k+/9Fy7X/2itqF2YmKk1ZzGJDbMDXPUCJNgpHFNWYMSbNlEa5L8F5RBFt75fV13Tafrp0mWbljwYzQgL4crI55NYg9XZiUpp4E6Gk5b9bEDraDI2n+tOzszwRsfPYv//Pu/A+9+y2uxe34uoO+txSV8+dxFjEcjPPTAMczNTDAajcwYdUe2VHm3tgq2trawsrqOL527gI99+s/wrz/1JJ67eAX3VtY8lRLeRaUJp90D6dRlEAC75mbxTW9/I/7e3/wQHjx5BJPJuBephybeXAYAz128gu/9u/8TvnzuooFprBdMQG0IoGHs3SNVN8A70WzxqcPPu9+ASNxLslSJMpJWuv1KZLCUycg3vI/2ru2bSh3cIgFFW2BULVUCNFnvXQyozTmE9g7oHzgcCAm98pnJGA+fPo7v+eZ34Ps/8B4cO7Q/IO2wctvLniyv0tBrdW0dn3ryafzMr/8+PvH5r+DStVudYzSvFC0BhOU7uh49cwI/8gPfiW9955vCDjj3v90ycKmT1s98+Rz+03/4k/jScxeo36jP3jywkSol7uOEWwZ4sQaZULJikXbV1oQx2Ncrk2E8d/aJH+tuCd3XyQ1beOeNlgeKE9FORGJ7neToPN2VUw07CBKVUZSuFuv3hlY6e5EgvIfLyijB1aEDC/j2b3wLfvQHvgsffN/XY+/uXY72acBaZVreQlytz/fGoxEePHUU3/7ut+LR0yewvLKKa7cWcW91NcqeE2nOvZMMgODGnbv49Jeeg4jg0TMnsXvXbBiPIV6VX/199OACjh7ch888dQ637y4bDx7FdOxKHA8ethAFKmwGJFe+ksNXsOOIyRmCITjfB0fRWD/y9cplMIfo2rulK/2eoREdpSK1vjuP/nYmwiD1jIlWAKpQjCw8iDDFMj30eHShI9Ovf+QM/ta/9234oQ99C1770OlgwEo7G8/a+gaWllewvLKGra2Cydg34vjiti0nGo1GeOTMCXz9Gx/Dnvk5vHjpOm4tLpsxdYsIrJPSBwX9rIh7d3kFf/bsi9jc2sIbHj2D+bnZZqTIcvHneDzGyaMHsbq+ji88cx6ra+s07Ix89Z9WxNFqbJSA20ArfaAUyCe2DgpFCJihZbU+20Y2bOLplcoge9/1YTrl7KFZiu49sAN5wpSdWZsbhTpgzhDcwNsZgNfJ93JG1cqwBrIuvTe/axZ/5RvejO//wHvwDW96DcZj3/jiiefa+gaeu3gFT527iOcuXsFLV2/g5p0lrK6vo2wVTCZj7J3fhRNHDuB1D5/G217/KM6eONx0qtal9xaX7uGjn3oS//1PfwRfeeElbG01ji6wXKQXB0q/eWj/An7wg+/Df/Z9H8DMZNzjY2gjj/l67sJl/J1/8vP46Cef9JQu9NtaJOEUBcjGYbOAEElq9CuAsIBiHXkDjSCmGonGF/gB4goU2d19yjDpjLjUkAR/BqAnaxTcwSoyn49V8CDElIeYM8H7/TgRroOe0uywRzim3dU5fmQ//sa/+z78tW95J04dPYTRKKJmKQVfPncRv/WJz+H3P/sULl65gTtL97C4vIJ7K6vY2NwKChYRzM/NYP/e3Thx5CDe/ZbX4nu/7Rvw6ledMnbz+j+XAcC+vbvx7e9+K/btmcff/kc/hYuXb9DgkLwWqt0INHr62Auu317ET/zSR/HQA8fwofe/c7DfIScBgAdPHcWHv/09+LNnL+D8pWuuR+WKkY9Qmz/8e7UpHj7L+CSIpjJA55jqLNq3RhDEVE/nrTDeiqeYIRLdvww+qQ4cgwinAaKzSCkyordEHATevj77Qet3ITQISqbvaixaPh6N8IZHTuO//I/+Kt7zta/H3Iw/D7WxuYVbi0v4vT/9Ev63f/X7+PzTL+Du8gpW1zfMQLbLu0Eyzc5McOb4Yfwn3/Mt+J73v2PwiHc3HtEIN7e28Nt/9AV879/9J1hbX6/jMiCk8mAIFysUAU4fO4Rf+Ad/G088/uC2c4fWZ6eXTfwX/+PP4Wd+7eNY29iMOg1RQNmrWYOBXFcqPQHiOSU7hZGE7D0SUO/nyTk48hi9hORQgL9/GWwOYcXqupa7SuycvFeXZbsJc2RSEjM0JAE5OGJp1CxUbnTEnpOq9+MhsI5lH+Ddu2bxgfe8Ff/07/x1vOW1D2My7k6grq6t49kXL+MXfvMP8KM//vP4F7/yuzh38QqWV9a6J9BQHMFMc9oHo7Ub9+bWFm7eXsLvfvqLWFlbxxOPP4g9837sO0/YGaFHoxEeOX0cm1ub3SaZOQ8hSAA1RULiSXVeCpbureL5l6/im77uDdi9a645z8m/ed4zrvz8qz/4LG4tLpsOGEwLj7fEHWAR7oO92eeV5jBSgTfJECIlCCDMJ6TSgNkkPyUH4cUIvCIZfJVJFH39OIHlqVVZ3bJsDLeBYUY2gYW53sTQ0D9utaty8nqzIYSoYApHLKAP6qmjB/G93/aN+Ps//O/jyMF9ALq5wVdeeAkf+b1P47/+iV/EL/32p3D91iKFKphCu76IuD1qV+tayIavdADYKgV/+qXnMDs7wdvf+BjGo1ETpbP+AOCxsyfx2aeexwsvX4sRwRyfQ25d7zPU8M8tFNy6s4y9e3bhra99uDf5z6thmZdSCg4fWMDl67fxqSefqRYe01MIz3dSCFPNkJGXSoMNO+g6yWDpr9ldxAZzCrbwBB5qL8bnfcoQIoS/EsVRnNE9e5p1KpJWikrfeBGI1FSJFaS8SRVXqJwhKAumX7v+X/vQA/hbf+3b8B9/9/sNpV++dgu/8rt/gh//hd/Az/76x3Hp+q3EDynUcj6JitTbKme9L2mkCgq+8Mx5vPHRB/HomROmpyGnUAPdNTeD3bvm8PHPfBkrK2vQKG1zMhFyClqWzqNTBCtr67i3soY3v+YhHD+8f9t+W1GrlIIHjh/G//HRT2B1dc3pk65rQk56IzbC6xXdjmpHrnMbyr4MsT+OGrwiFfkyPrRqKLw/GcazZ574MdeXe6kwKbZBNpYwyJyTspB6mweRBiN0EB0kC8cPAZlDVdqj8Qhve/2j+JH/4Dvxgfe8FXt378LG5ib+4HNfwT/+uV/Hz/767+NLz13A5qZuiFlCGs9MBcCIkSPPw+y5c/1eeVtb38DVW3fw/nd8DfbM72ou6ea5xWg0wt7du/Dsi5fwlRdeMn1pNOhFiGTk2bZuLS7jxJH9ePNrHsIM7WSHyD4QtUQEC7vn8fmnX8BTz79kwBdiAUf9CgQRkf2TT0KDnTibCMtA/YVnJMQNuAjZn84j2LeYzn3KMJ4788SPcZixNWFowqMUnFQ3Ln4swxzIBhru0RVRCw8Gh8LAGFmc5SN+3x0oDuZ4PMa73vQa/L2/+SG884lXY37XHNbWN/Dj//tv4B/99K/ij77w51hc7p4BiMck9DPvk+jg+X3jMa83G4YQPQB3l1fwyOkTeP0jZzB0ZYPcM78LtxaX8AefewrrG5vdWFg/bkThbA/xyyt2axsbEABve90jOHpwXz9SN/jgaDESwWQyxq987NM2HgE0tNBSOG0v4CgQeXV9mS63kUEIBHryAnGCrPXIwGHzWhqnHWQYuYeQIWpHpf4oXSN7UxocnS2lqgauxiHKCssQwlgEiELG5AqSVEvZdF5FBO/92tfjn/7of4i3vu5hzEzGOHfxCv76f/MT+B/+5a/i2QuX62QZxm9mIEwCTcleVmwUOTfWsoRKVV83F5fw23/8JDY2Nl1PZHit/H1mMsYTjz+I17zqFIoNRN+QQ5rGMoiOV1f2J196Fl+sm3YAkFe7hvjQ8jc+9iBe//Dp2Fd1SN8DIH0ofYoC5iQ8lCzSdjIYb9Q3G5ECRTU8yXRzJLoPGbrdKeqjgDbkROz1KzaprQwURnBzktpex5Jva1gtyowOkHlfbeOfKrwvgypqdD92zc3gO979Vvzc3/9hPHjyKO6trOEjH/s0PvQj/xi/+rFPY/neGsmWFElXVE5kqUKVjkYiRUZAI1FEsLm5hecuXMFzFy83c3aWiw3zsbMn8dqHTlekSvw0ZXAdaYqlBrC0vILf/8xTuHnnblhezZty/Ju/H9q3B9/wltdAB9PtncBCUdB4SuNZ1eSpcd/gt5PB9evgU8wAsy6inkr45/5kmACIa7jEiwrjWxGFwlREb8tRMwFKR3wZTMOgp02dQxMi2hvVuF3XbynAvj3z+K73fh3+qx/8IObnZnHlxm38/G/8If6X/+u3cfHqDeN9POqOJkzG3eOak/EY4/GoLsN2uXu33NgtgWo/o9Goe/HtwFXQPSnH8uvjoVtbW9jcKhiPRrh8/TYeO3sy1At0Urp2YGEPHjlzArvn57B0T8866QA0+BHSjemumFF96ovP4Pqtuzi8f6Fp+EPzChHB3vldePOrH8LMZIL1jQ0aLR8HUSQ2oIJH99bR9/BiJq2/vQyhndlFcWMPqRrJYt1XMJOyowyTYny62ZX6r62oaDoEn0DGJyFooAw0+4jo3qoi6e6yKyWTnZ1MsGtuBrvmZrF71yzm52axZ34O73zi1fjBD34zjh3ch43NLZx76Squ3LyNb3r7GzA7M8FkPMbszAQzkzFmZ2YwOzPB7GSM2dlJfVPeDEYjsTdkTMYjTCZjzTgxmYx7b9Hja6tOnu33VsH65ga2tgo2N7ewvrGJPfNzOHPiSGiXI0SeXAPAQ6eO4uC+vVhaXonoVyNj0+BCPVfgsy9ewsUrN/DY2ZO2Q5+voZO94/HIHmd97uIVQ0YDsVb/wSR4nlj/oWHubHlnGQBa+HCD4Y5C8HR6zKz2v70Mky73klCpJGq9yAdaK2YlBFmkn03UupPxCAt75nFg7x7s2zuP/Xt3Y2FP97lvzzz27ZnH3t27sGd+zl73ODc7g12z7hgPnjyKIwcW0G1uCV7zqlN4/MPfgcl4hJnJGOPxuHmmJ//mlZ+h3duh7zu1B/pG3/qdaZ062r3QLM5X4AgYUBgIA6RXrbu+voEnnzmPb3jzazAj48DXTvoQERw5sICHTx/HcxevOGhrBlnISFPKqRhnLKUjDMb2fciAQk5F9VwGW96h/rq2eYVrJxnCu125P95BbPHrIlGgK4CMBAu7d+HowX04dmgfjh06gOOH9uHoof04dnAfjhxYwMKe+e6dprMzmJvp3ms6OzOpr3Lsvs/MjDEzHlsas90xivFohAMLezB0DR20Yzr3m1e3aA0ZfMv4duJHRHDk4D7bQ2nyjLih6WkDaEgU5ASfe/p5bGxuYnam9yrfkCJlOUUEBxb24Mzxw1o5ZiqBExobA0vSQwDNjsmYZWwvg4T9IOWZ+xX2t65cv+f5xjYymIaMUK0UcjGdfUvX7cxkjGOH9uPsySM4c/wwzhw/3IXWE0dw/PB+7J3fFXL1yXhk38fjLjffbhmwtYmVr53u57o7bYy9EuTfbud5J4dp8Z7bHNi7G7tmZ2LIFgdTJwRHYwBsX/4cQcFTz18M850hPlrLrwcW9uDsySOYjEfY2ip2HCd1FxjrltSLPwNjgsL3j1KavJMMMWPRJf8IC6kTZoj4gftVrirARFOODqkdoXfNzuDgwh686oGjeNWp43jo1FGcPXkED548ipNHDmB2ZrJjemDKafweyltNrFSWDa6F6kOhP/++n4gx9LvVT67XcpydUjFuNzc7g8lkHEMz3JACbUF6ETN8wGvRs+cvY70eWmxFhBa46L3JeITv//b34G2vfwTnLl7F8y9dxbMXLuH8pWu4dWepeyv5+gbW1jewsraONe2ndq5THmXGncF5vR8ZisntfuTpkf8IizrUj0WpMC+gtL/Wn7z3a1+PwwcWcPrYITxw7BBOHz+M08cP48yJwzi0b29zgIcMaicDZlpDAzB0DQ3ekLFu53D3K8PQvfuJYENXlqNlmDOTMcZSJ/T1nJUvcCQ+C1kD2Dbc2lbW1nDt1iIOH1gIfOwEQnodObgP7z74Onzjm11nW6Xg9t1lXLxyAy9euo4XL1/H8xev4MKV67h5ZwmLy/ewuLSCxaV7uL20jJXV9ZiGsCnehwy9NKtQWp9DS/3p8QT0ehvNl2DpE+VWmPzLv/dD3RsmtjFgWPv2IO5kfFw+ZEhDqy9D9bcb0KE5wU5OkXloyTfE63ZX5qulKy7b2NzqTr3aDDClSiHWx5vOSuT38o3bvec1WjLsFN31Govg0L69OLRvL97wyBmru7VVcGtxCZeu38Kla7fw8rWb3buqbtzGtZuLuHbrDq7dWsSVG3dwa3HJeb0PGcJNjTYmg6dDfTpULgQuWk4OMhlyhmzA2Ui3SxWyoltovNPKzv2kTPy7xfeQwfHvITocaTLPuT7T2e7aLr1kvtbWN7rddYsC6AGqcOznJVjli8cBwG0zvj4/2+k51891sq7HY8HhAws4tH+vHVsppWB1bR3Xb9/F9VuLuH57EVdvLnbOcuk6Xrx8DRcud1Hm9t17KOk9UaYCRf0QZDr5exHT6qR5Rj6EahGo+02T6riTOZT7Dxla/p7bDA3CTpEgXztFnJ2Q/H6ixJCxb5d3D0XS3H/upyX30soq1jf0xWce6v1JM4I10wenVH2ad5b8LFfms+Xo243vTo6Uo7RINy964NghnDp60O5tbG7hztIy7ty91z2huHQPL1+7iaeefwlPnbuIr7zwEs6/fA0ra+uqxdq2ZjthbtAV6n7FUHbmtl9Ijx59zCGyIQylLa9kPrFT6tNCmFZakem26AwNTL7WNzaxurqOLRSs1ZcQbxVgeWWVHs6J1+bmFpZXVu0FZXyNRLB71xzinpdgftcsxqPuZQRzsxOMR6NtUVd5L6VLOe6trvOow/JnLrMg4cuc/gwwrK6ge0IwZwCtyf0QKA6loUPtW/1wO5FuM/Tw/oWwi765tYWVtXWsrq5jZW0dtxeX8PT5S3jymRfwmS8/h89+5XncvH3X9VGq3CSrRQX2HNJHbVGZqf/UexNmcMgpwlDvEAVy9FCF6Juvu2MNW9jcLPZ9a6vQvYLNzU0srazi7vIKFpdXcHf5Hu4ur2Dp3hqWV1Zwt74BY3llFYtLK1heXcPK6hpW19a7z/UN3Ftdw8raOlZWut8ra+sum2UXldeMIr3ftLTBk7lUv0mP2s7vmsVkNMbs7BhzM91G4/zcbPcsxPwc5ma6TcfFpXv2x05aaI8ez5w4138KgkHkB4XuN7L+Rept157LWvUm4zH2zncvcgCAB44dwuseOYPveu/bAHSAdv7SVXzmy+fwmafO4bNPncOFyzewvLJqY94d8c/gwU6Zogrtm0xaqZFeGUXyvdW1dayub/jn6jpW17ult7X1DaxtbGJtfR13l1dwa3EZt+8u487dZQuPd5bv4e6SGz1/bm2RAMq45s4BHXv6jsbYMW88c4g1JwbiI4hu4XD06crtfUC1mr331vLY6E0FWr/g3spaJ8Ny7MYndeg7F8d/Bh8ba9YNqQwsn+DQ/r1h7IZSvu0i8P2mta1rp1Rzp371+8xkjEdOn8DDDxzHd3/zOwAAl67dwpPPvIAvPHMeXzp3ERcuX8eNO3dx4/Zd3LyzhI3NzToOPMaw77bJzCkTMwDA0Hfp3gru3lvB0vIqFu+tVKRexfK9FdxZ6nK/29XIby8u1+W2zqiXlleweG8Fm5tbPmBsc8aYl9mkyX5zxAG6P3hIdbINBroRxYUJ50STjVnrJf+wolq31MHqoXX4Y45RyDDuLd4tndWIFKMTy6CH7F1ZtW9dfyE8OFLTEga2oblgjvhL91bx9PmXsbK6hoXd81jYM4+F3buwZ/cuzG2zHzVEL/c31G4oTcsynDhyACeOHMD73/EENje3cPXWHTz74mU88+LLePr5l3H+Ujdpv3DlBq7fWrTXiZpy1OhKweSzT53D9epJN+/cxc3FJdxedBS/W52gS1/umUOsrK13qwFZmIH0w+zNxq4OaEn12AgEvmFDuZ6kNi1lRi0C8SQtaqiMWB6QGoD9DTuzs2TN4s3cv1iQyhchUFz37vjKewymAlCfLRlQ+uCgOk3R7uihfT3D3W7Sz2WXrt/C//x/fhRfevYCFupZM3WKfXt248C+PTi4sAeH9u/FwYU9OLCwBwf3dZ+75+fCqeGhifzQ2LXmotvJMB6PcOLwARw/tB/vetOrsbm5hSs3buPFuor1wstX8ecvXsKXn7uIZy9c7pZ+TX+CyQ//d//C/tLNvfqp+TYPtCNkh0T6+J7eMsbyoLKP5IHrlZkaYsoAOOrGao6CLW2qEYUUq58aSeYF0ab8KIsbrw0OSq0X4d6QjOmaw0lMA82xHFQiiwMymLMR6706wMzMGPvTXzxqrSYNIfTS8gqev3gVTz79gvdUnXMyHmHXXHcKeb6eRub/9y/sxqmjB3HqyEGcOHIAJ+3zQO8PUjJvOaLcT5rXkmE8HlkE+bo3PIq19Q3cvHMXV27cweUbt/HM+ZdtLvLshcuYPPn0+QoqES+FJhqsbQ/UA2icr6YhDhhwrd+etLJzUH1Btt50T9Rja5nE+4AjLzt+M5WRHhk6t+nshkFRRJfEm2rX+ZZ+h7FtUwaNSBkwvO6pIwftDeHefXsPpHUtr3ZAaWouzuL6xiY2Nldwd2nF+SHHH4lgRg9wTsbd90l3LP/owX148NRRnD1+GKdPHMHZekLiwZNH7WhQyzH+IjJo+cxkjOOHD+DYof14A87gG978GnzP+9+BpXuruHTtFiaWtRRf1iuaUpQSUmyzaRo3ixfxjQAAIABJREFU71+Nygv9XU3dZy9MQvrGT8yHteLmKwp3+E5lsW8dWDVSlbm7achPRmVSGkk3ZJ/z9j02/LkAVh3pUtMj1UXvD8WYWFkGvYEAGGYcteDxV53CZNx/tqO1qtjSv6bJlhGwzhKPqGOKKsNWKd0S6upaL+159sJl/NEXnrG6CgqTyRhnTxzBI6eP49EzJ/Dw6eN49MxxPHjyKHbNzWCmOpR+smxDMgztr8zNTDA3sxeH9y/gzPHDvA/hw6UpgaOYvu5ePCcWGuyA0LTioYxIiio0mPkYeXA2TT9UYSW+/a0fDkwYqstpkW9u6byaJ54aJ01hltZ4WtRLZdBfXRKbF7B+SvdG9KpPm2/xokFI/2pqWus3ZTD+NToUVyPx/+jZE/aOqE6N2+8xuRq7OjcXl2xjzzfElUYfkX2cq/6IH6kIIDRG2NLHhQXAFja3NvH0Cy/hmfMvB3DTP3559sSR7v962vqBY4ewsHsX9u7unqNZ2L3L5i7ZCXu8JmeZqFYLGaYasw1HUlJPeRzdG5Mlcy6ztr4K2dFyHX43kRmxstukh16EsJSHw1pehrNopmmImGN2/HF/Ka3hUFHUiI35Ss9cpt9ceTbStX6cwPVkCBFWn39nLy8Fr37wFMbj+Cqa7XLzXH7j9l3cvrvkPChYBVBh4ycZlB8FsBBd718GQLC+sYnnLlzBuQuXHagAzM7O4NSRg3jgeHc49czxwzh19CCOHNiHowcXcGj/Ag7v34uD+/ZgZuILq61oUh8hFe8X1WvTpI/MJCC8DyAqAlBZVjIQF0oyUhWvFCavEIQcnD8ZsVqeoQZV+cvOwOgfUyyE9NBQO0dEUq5oH50lxzQP6PUddAJSNB3ayc+79+ZiQn1TlFaNz++aw+MPntw2rWhdOi4ra+u4dvMOVtc2+ilzYMdcnXQKFNPBMA7tJEPIOtCvs7a+gedfvornX75qdMajMQ7u24Pjhw/4w2oH9+P4kf04deQQTh/vjpEcP3QAc7MTk3li3kwdSOjUPwoLY4ZIvGsYNAOXlB5FZfqKSuxLHdTuFQRn6oFrdlCl0vqbTyxrcEgtQ7U976WHotUwLZ6K85nCSCMKKaBWtA7zGO3H+Q7LvT0ZAjsIY1kN6aEHjuHYwf1RL9I/umGt0qT17vIKrty8XfvhQdcP5c15YmDK0QJZl1GlTRkskS1qh93SewAp00X3ZWNzE9dudidrVW+j0Qi75+ewf+9uHFjYg/17d+PIgQWcPXkEj545gUdPH69HN2wuQGGPeLI0kW+kCvZ8h6ZalvoV30vQ6lVAdbyewRUKoyyvAi2ykXaV2oZbP4lWnuOE+QKK/ZGOkMax7HWAt412zAN8sAvUAIs7otJj5wwRYhsZQiqm95yH1z18Gvv2ztvYMK/6PadSnFLdubuMl6/dAlmJzeNEFBTY6RNiAvwn/XrgYExvI4MEA9CU3pSCuACCIGv9AaBgq2xhcanbU7tw5UaVoXs4TpeM4zPV2RmQjc64rUZCp1YDotZ0B2nFhgzaBpel0ElWcoYeyjIyVT7CODDZzL6RJDQ2unEeI6Ts3nPMmuYY+qV7WqQ71tQHavRsmga16e3FJBkUrNwx1WDqmIjgTa9+VXjeRctb3/U3G+O124v1XJXza9mgHaWmsbRI4M7cS69NgJ1lcAQA+I9RMr2wqNGjp/XiONgq9VaXFq6sreNmWcKIw154k0bgGjUXFEsVAvRph6XUkJiE5xDISjOBnI4oP6VUbWkOqf3U8nqv1N/FQlm9Vw0qDgClAyA0Np7Y+Ao8/LszGB/VEGIGlp2mgP4IQmBD38xnLBYVraYIhbQ/IEP3J6cQh8LsouDE4f143cOneyd0+eLUKciH7tU6V2/ewYXL16uhueydVorx7gAAu6O+oiXGG/3NkZ1kIHRKWy26vFtl6NVzeyk6DvchQ91VVxOnQWclATaw+pC4MmNOot8buaLPEYQEd8P1e0KoLoGegTD3UcO8fap35TlLQq+Od17ZoI+MdMYLyUQ278unhFSEdIaeJqeSc7nMF2s7IT2UbWSIcyR40K2g8vpHzuDsiSPB6PkzO0JO91bX1vDn5y9heWUt8FwbOI6Tgau+LA1Vsya9iYKnYEcZHAi7fhyvGHw8TbdxKWruyrfclwyjbgGDI4GPmr2WEoCuiXsa43Qtn/bKwTGYuKK2GnKeKJozEt8qtAeGiLqwNmmtWX8T6quCmNXCfLJsJX3PUQIl0kcXS7r77DgUzYo6COuF+lGnKj6UQzJwxDBIq2M/Ho3w+kfO4IFjB3tzB54zdF1K7zcA3L23iiefOe86rvKajYS3DSONmY5H3jOpsguB6oAMzIuNS0nlqjLWN4GqgeJ9yjBSm+zstASCYvHHOQlKC06hCqgEegPcFzbMNANbEo3EtFWIL1eQKrK1ps65KAGYGwlo0w1sfL3OrUOPqr5ZFmTIjlkVapNpLSM8UHWYM9HNIRmCxsRrlFJw7NB+vPGxs9i9a8544bEbWnplvheX7+GzT51ToaCbs6IvJO4hI+tL+wqwHe8FC+7LwEBFOG1dsBshfDd0DWB/PzKMNH2IhsaRwRGkQ6fIhpNyoQhM/R55LTNoTQWInVJZL73Sf4oZd3/+k5XkCMhRSRIPbiDMs94X+BvJGaEdnXQ+FBYjWBbhMSKAqOXRzolGSwYCKuekq/PomeN486tfZfc4Slj9bdKnrVJw7sIVPP/yVWjEEusXidHsFGbZSYZk0UpvQAZWgdC/+pXLSt/oEhjfnwwj3fSye+YAyl004LhrG3M65UztpKdwZYQHgCa+xYRoISz7ixpDXU9H6Rl7aJ+912RTfTkDOvkrlrbQmJXSTcqonoV+7iOMuVhbcyiWQ+tlmxr6TTJYpAECIMzNTPDE4w/ikdPHuxoS9x2Gdqf52trcwv/zx1+sf0qg81Y7cSDxyEaMcmzcpV0HBXa0fkAGjRLBFgqXw8a+k5H74zZSJ9L3J8Oo71geHYrob2ebJzMhVqTQUNKIsjN2dkSQKkQ3h/JqcGZnGkprOxFaopN68KJQtAiwS3k8Iz9ttNhGm8lEBwy1L6nRlK0z0dNVJCsLwOK89TKkHDW3kcEnri5DQcGBfXvwxOOvsjebuyo8wuT9hlxvZX0dv/XJz9NUJxp3S5zed5FoBZwCivPQkkGjhPPmNhjmPgE8HRQ1awDwimRovA9ald8NqJhnwTw2CFzHXcObejCnWb77KrVuRHNLXSoRS8tq9GDlQLIh8P/Urw52I5e39EXbG7k+X4Y2lfcQDXj+o11pWsS5USGabCKFNuGgEV5hhhxqQAaPqDwsgl2zMzha/9jk0NWaO7CTfOXcS/jzF18OVuOGmHRkTgYDJaXpsrFTe9mQDA2O3cisM71D9etYFbWzBEY7yWB/MIUn1DpGPJnjXNcGw8KPh0pbPXIOXEadsErrnt9XRDD5ya5cERLpsQ6rI/TSAmOthL6lkHzGlxhdtmveuOtM1vkUU35yRFdjdCKw/ORo2k/LMEiGgMYqcyXFfzUor8pxCtU8RiGCj/zen0Q/DIMARCOOiY+rUdwUeqkI7VU0ZGhdeQUxsGagLL3br0SGkZWXdAISDrxxvZfpO1KHkEsiY6B+MAAzbPZ0CQ5QkhCc92uY8s0Zdkrqk1Mc66c4X3n+QXOVbqC8vKA6EvHgrGj/VYNFzSTqI8ggAgjJEAx5exks1aqGvryyiguXrweDbx3VyJc6yp2le/joJ58kXfAYlF676Nhtc+63kmBNWYZ+OzpuYv+ShTVwKGQa9ynDKDqdo5c1LLRuS/870LJxpb7UUFoCcghlCNbONVJomiWRv4jilIsTHVeEuG2bWG5YXa3YOGaHHj2JYp0fOw+O6dkRAAnL0nVWZOlF1bOlQsXlM3p9GfhytQhuLS7js1953l883EgZWt9VJ3/4uadw8coNQ3WXAT5WKkO+xO+GYjLY3j5SQwaOOmHH2r51+jENWpVC9eQVy2DPf/v5cw11aoidUYqktImEN2nqvSAYTeRcWFQDSKMr8HydL4l1TAP0PcwrOBJWxzOHIhkrzHtwqgJ6qKdIo/dMhg7hnFXqm+ZMHRkfUO1HFxCcx1q3+KKFB7m2DNpvTs83NjfxR194Bn/wuafQsj1OmfLkenF5BT/9qx/r/mqr+jrLZ18jwvPVO8JiHaso+V5fBgYDyVEnoHzUFTuT9fkKZBgZmqoxJvTUfwutAESiXtUnwVSFo0PKAdWDC71tTm1fJ6i8fEaEGtGifrYmxMEoCGaF6CbZObQ627QCp/WtTuQvKj/zpewK0VKemE7sqykDUopRZXjq3EX81Ec+hqfPv2TzCb56x2oALC7dwz/7xd/CJ598uvtbEAQ6wbEkF3AGEE/SBq4TYDGWt2Swytl/xP4Z6EPi71cgw3ju7BM/1t2n80AV+UQiU+YenNL0+CRm4IOsyBqX2pQiRQXhk6USaRppUlKOEgES4pKpt1UZ6F79HlbG7N1KXl+q4/vEnzYFqV4XfMT4cLlMUTZgvCKl49T5Ox+xaMhg6gjZOHT179zFy7h+6y5OHD6AE4cPhEcqQeOxtVXw4uXr+Jlf+zh+6iO/i6s3F+l+jEw2NpR26DKzL4EXlMaL29xRLOjtKEOI9hGnK510ZF0i5r9SGcazZ77mx/pr1dy3H+y29WEVrpTGA/GBnY6eEfBjEkrRjJEQ0pboLO/mdiQQnEzPadjgA8oQErvlwVMdgwSiVT+qLIEXNQIy1vhXacjZrJ4DgsoaJsCge8RRTwaI69SONzt4bdVI8eVzF7C4dA+j0cj+Xp+I4O69FTx74TI++qnP43/95d/BL370E7h6azH0SaLqiBILOn7phLMIgVwETVUJO8p2MnTqKaCz5M6bDjnpN/wRxb+ADLLwrg97QsBGWb0cTKzhgUrYdwzj3TAlKOyd3ie5I8AGC/+Zy7O9Oy1xmNX6itq9VAvu1MWNLm8Y2Z+BSnriyNHRQd0EUjrMIzOK/n0g9k31WGCWwV72RlWHVpD2zM/h8bMncfLoQezdvQsjEaysruPyjdt49sIlXLlxp9emf20jA3xsG2xvQ/H+ZeiXF4sSodP/DzLI3nd+uKiXSB1U1DdGlAB12hrJ4xInNPi8fNsa5DD5MsPYRjI2Hq5nhtTx7nU9tjUjQsdE/MlDqjQkaa034jB0i/WobYg4mR929pL6ENdLkkEdQuc7OSVxMoXK+3W0Jt/PV8xWdrK+lNtoi+2caEpkGFlupWlHcYOgPUc73h2ioKKh/rQJTFemO5F9VIbdDzwJyFWJtADdiweKl1taBfhEzstMHvZeyzOJX7oHDcPMl0j8ZJGL0mT5WVYSoNemhE/7rsZRx8L7a8hQYH7CV4g6SrPq24/hlNAmIC031fo5khePlP25qZ9gsPZ+M2DAtMkw8omvHpKDDXLRmrpJVo2Ppedfzc0ejgAmfcmVTPpS0spwANtOk72d10Y603O0nObAfMD5FpWpVLm9n6T6rp7ZqCSbTyPCY2RdOWgoRZ9DSKg7JIMBSolyMbfS6y8QNB5baYeBQ3b02rxPsy9fhPmke2DqZBjxLrReBsRkKLb2zl6llWu4S1YDMy77qZBejUDblu6en4Hi5Vak3JEmm9oWzpMhSCmk26wMktl4pwHIiK4R0groJvGpfYRJWzXkjAHB2EkOu6cyWJ0hGTTi1YhjAKfNIkgVe0CJ+2s4oMneL7dzVsKVUkMCwG54lS9ptJkeGUZsEJwkOappaNF2FHREU4xangcZtggXmcroUBt4OJS+MwbQJXr9oARdzXHspTZkfeG4MDHnswodPKGoRo4Z2vltllezMgMP/nSJ4Gd6lQ5HnWEZQscqe/Rm78VSXpalYZyBZAk+b+lLzzG5OUeHsIAe09Te9dWXYeRnxfkWD5yGiwpQtLKRiTVkIwGDVPETMA/vpV0kt+bO2UEs3DZ5qM5BYbYAPqGvCgtTBNa19dWgX2K7JArUyTsHJxoc4fS3tHZ+yaMaMiRm0DcMbePR0wWjZrnPHg2B60iavbeb+zh7BNeigcjyVZZhZA+sFH3YBoij7J5qUSI7bzBOQuA8H9D7QgNdKqImA++jKDlWsX+cRc35M09UZkvDAHTDplRjj7vBjGaxr4D0pCc+qOe1SVEqbuCTz4glkChVfyZbX4augA2E+eFrCJGBlkeHVJNoOLj7KYPW5e3FPvI5OeHUaIpkGHnK45MSe7WistUwlmFeXSjJqFeYeYpKkuvAkbkVEUH3+Xcjj7TDd+A0TPpNaorCq1D+qXGTdqR77Hjfvoxod8mQpXv3VJXR9J9407+/YWnZgAz9yUk9n9TjcOjqt2+BMHcZVvu4ZYoCnnXwuDjie/n0yDDqA3E9xcnHFhCF5By+F/okO2U/n4uM0m8yRvfkUgMJG6pGssw59VfpSeXRAbh4XU4srZl7oL7KxCrxKww5eBAa5eClSO+beCpWmjAnvgy9tpEhCE6A1Vt14+jDbVmJQY4h2soPDRIvRgyUc8rUzJSmSIZRH+z0aAZ15GEkZkvFQ2F4loIdJYeuxHDmW5m3rEpXn8jTSpH4FpcqVLcCRsqx5ckqAuX84Z2p6njGAB/LVnqUd3LkEpATikVXIceMO9qdcxdqVitFvgzBhmXwts5PSaPfpSY0jmGyxGQUcDxy+x9q6WTyY+muBj8bSYsCzqzrhXL4/sR6emQYmYOQcbgxeJ+F7nX0S2SG0qSAZBziszNoWLRQSwZKUOu5XnRKdx4xJdxXmK20+6dMnV+jwxGnR7w4+oQFCHJKks9JSjLqjo+SdToIpwj6ccJVV4F4HqcGzYygzcsxW6uKeGkvPa5tnKw7gW7YlimUYWQHs2gC2f0U9+aS7EGSddSfnkrRKc2wkqRtiyPngMfb7jN5dukZJykqfzJaqYeR43j+LlE7pCyWU11TyztkUf4k6YT4VDpCO8wZxer9cO4/TnDaMqSXSLcdKJup81hCUTYV7TLS7J89S22SVca6hh4QpKM2UyLDyCaAhGoWtdWrq12bQwf6bipuk25kVp3bNKJFXCHKB9zo1CyovvZTFRnStJQLFnpE1pd2OsH07SIWqUhxhctKFD7jYWG+VGm1rPmcQP5kUGmBYJaBnN9eJbrttSOEwgBAuwkAwydw+238+1A/UlNaspYpk2Hkh+L8hqgRBEsmYyCn6qVHhraApjO9E7mZDzVgRszIpwkTbrBuOWRzNeMnnpnnpT6xRhLaSFVeId2oE0qgDQpWZPQilrPynxf2JUcKa9SnpU4ZNLIM9V7J/ISmTMRXu3rPtKkzcmBlfhpPrTUW1Y1YbyndWGg4/BTJMPLB6AtnL/yundFH/eFOwKsoXWrug2pr6dxLBhKOFDm8VAYcgVUa1l5sZ4oxhvt89jqngGPyAQYYPhBRJ+Gqssq2ilM3pHmDReS4gBDbJhn0HqWhyp8al+MJuWvpq98E1ZdahzRDAv+2QdpUAFwGSXQk6WMKZRjp5JiXVwv8vKt2K/U/fdS01MGueKhD2+vb1u7tVjXk4J1uhsW15cZS21jgaOSEdLPjtyrY5kDk9IUjmTmR9+yrSTFSeSxhmYLXeuWKhj6YfVm7moYgDQOjgW3JoHpJ9UX7MwNk+FWLK15U25q5FWpnLQaiQSvnb1atvAY1TZ8Mo0Lhmu+pA9dxJaE0lVD6tOWkS4QmLLsMG664ExYVg+rzfEJpVdpstqGNKcLr2nKfVa/OXVxn1jfDjdCufTEx3cs5pbPoxQ5Z6VOaVFjvjBxAGqZ+2aAMpIP4PfEY6jAd5bPEtnQ7PNuMHZ43UBwhWqEmp8VgutMjg0WIGF7IK9A9UdYZCB/m00+NHYnxEn92/JPVUUrTY01XXRKtojQkF6KBVKLg4yRKHqwSx8eBpy4jFopwDf3QIMRxrjOErCceRIoUEgioCsQdcxsZ+srrX1E1HImpr9C5ddQzSl15LLbMLNZHWrk2WmysDgzTKcNI/+Qup0w6kewMxjfqWnwra4yiKm+Qga2D6hjzbNQhIhWrFx80UufSB4eIweI0CURq18X7yqgf9eMRxin0v/NtUn4+PCbWJ0dJoZsS6Vk72UaGoCzXRY7oTJPz8HzFAauglG7yCqAxMXRUolMwPxseMMHITo8MI5vsMnBXBpSvYuV0GK3S7wZJHOXcfvu6oY6CcZtxZqOQpAmmp07AkYQjG9NmRxOqJ+keOUtuG8INaZ1lCJEqy0eOkHQReSR+cvssQy+0UIqoPGT1bYfG2yI1Oy+SQQ01vI/Op0yGkWJZv/9quGZjxFhGf/7FyMWD3HuegNux0NnbqNRWsTrjCs8dIJXB67mjMZ/Jbf11GgiC6rJrP1eMUSkpe7i/ThqnqW29fS8dHpLBFNO/WnPdXv/tW7X9tgR27OM+mnsfUyTDyHKtXkbgnuqhWqB/UcgdO4U3wF5UYHMPEQtzQ0YeURscluBHLPiVNAiRgXcTzJmFf+lddRzqmxkr4C2K+qFPfUGzgEQXJkNRGYJeOCrRfaNSXJdofbZl4J+hot7OixP5fhaiAPpXfuIDPdSwRSxfZaDcbqd7UyTDyGy6xNwtrrnX/9TwhDNkQi/O7UTHPjtCsf6sNqFlYcfQlIjyQDu3xDKaE6V0g/rxA2POo5FgpUt9eo11ojYYDLfYBqbzofG2epVFLD7Z2v3T26dQApbfOgAMyWBOJ6y3TgZzzPqdj9X4+LWBkN+20t9ENCEgZAeFv4S5l/atPbolCwPHlMgwKsoYI3fp0LeYkVUjpLxfghYQDCdczC8bgCElQruwEgX+SuWFfppOVdHqSPpViAePKODfgEU+fe5bakTU5xFC+0pc9zNURYVDS0CvtMMQutd1LBu9yqIbzaAMKndWeon9BTMIE1KKioUYsy7UuTMltgPlk7CWh88c3HvMupgmGUZ+uyJxPezn3ldXmUKaZDxUBdCsXbysJwl5Ru+YRagXVKYe2peJwkQ8KdtwVCYn+koT7Y6MMfNrRdnT4Ue9A9s+QMZXdv4knySerYwHtSGDB2d3mn5dQmNKN4kSySD1e0VPbpuNtuHh0rvHqzmpPYHCNMlgDwj5J0UGSlWK9B6D91QmpFDJc5MCwmSyxHuxjMOnCuk04+50oseRzOYR3taOzRty1MhgPBYbmJzvhoUndQApoW04tsL8soxGW0zXxlKhz21kMI9VGYTq9v3X9BjvV4sUP30A8Pur3LRMa73VNuILfKuPLv5cQyyfFhlGvPrJ3sfnZYxudtzgbKkD4QpKx+nzA0XZd1TwwDS/GS/xF5mk7/l+YtvzTD3OrTx2zm/pSuWHWGPBPatUvjj9IX55/AokGjojo0YmH/tBGQIjVq30avicqCGDkabTvazf1C/z3Z8gS39MVTai1V4B+urLMLIxyGHdEnTUQXdDgTLFzpRzn9IoS6L3lki9IUkJNxJNnZJGQtwytovfKxF19DxVNGydJHuIVbRnRYfgxtHABYFOyp2Os6X0uG+xl8RRbLUIUoZlYGUG3fWPOEt2cKptB90kPeSTwJEswnTROgLhiyA+pp7uiP0OIz0lMtgjpIbY8AeEzNtoMHSVKfiOcafeGG/oIb2wgSYShGsHCY0KVb3CivKcQkTSyV49d099atBUxw/KLvXV9d0cysqMx65zRhxhGXJqkMjXaG68ijk1Db7mWNRID1cOykBlgDuu/1Fyr6JL4FRUAaAkGUrQLe/1BJtlYGrEq3gpcjIM9g/0TYMM9gipnbMvjq0a/jWtKghtA7Phh9lrCfeLMaJIR+FTktIs0hUimw2PQhQz6CxQqKTwSeVhqY8iRH5bnK5tW58JvdzAC2zDwuErKqm4bv25AR0hqPK6n7r61ZIh9A2jSSHVVNOEHU7vlI7Ee3xwktmIz4oM6QI12+WTywJ7g+MUymCvoTE1K2IHhE+MS/qtdRJzIapYLTfEsJipEhsaI7ZNAJqYolyfBKayMHD0vSPbNzSxZdgqYxhEOsKiiOad+sA7tQbfJTp5SAPEfIrl78tQNSTOQRSD9F5S1NK6xI85KYFBCfe3RUIirpNnH/+Ox5gu8inUaZFhxMQ19+sMVKB5NvtrHo+wmx0koe9sq5xLsiezzWRbEnVEQkvVhgDIzmAhqdTB6fkq7Ub7SlmIOGTc4diKtlH0Vk9uIYiSUx4LfWeaNrJebH1W5lsyeF+esxu4qPxA1HUoZ3oMZE48qCQgZ+038xNcodIiHmMqGQFqGmTo/iwvR3Nul4zfUL0o02R42og0YdEfjUuRlzqwsJmUYZs7ahw0qdZjHbbbXNMeT8NKz4Yg8F3mzJykMnW60hdEeOhLqm8RINNpKUM7zn3D+m7JED5hovedJl09FhppGBPnf6O1Zrqe2DR5HWJsimQILyrrP93mZHSeoTN1oxzy/xIZY2NiSRh586AnZ9Bowmv25oyDSkhtmB/ro708GAT2H1BnD8c8ihoB/F4ICyURtUbkyH1c8T5y2yjD4HPLqPdS1OKoblPbUs+ahXrOEO/0lsRPUVswFbgd9PdvSuRtSmWoq0zFBTLmnctufGvn1ZBtkqROot89QfQ5hKU0HkGMSY6tnJ9ZyiJ2G7kPXaWy1aoS2+g/hfowRdO8g/0k1XVeSKYc9gt9N5kI6tgvRcm5XJZB1XZCegi+lWTwP+rooqsMAoqkBeDHWXn+pqPJRqlvLCygKEg8VyKw6Sq/OKDqy1fk9GEp51X0r7IKpk6GLkLwhM5GoO5MGxp6CtQL/SL2F4aCZOAyuLcWmCFH1CZn7IVMMcDtbepYm7RRJCkKFFcQs1qYT5atpO8MGLWwt8gAikzipS67OgjrhfpRpyo+lEMycEg1SDNAYSCKffC6u7DDa101ahfZjbvQbnA+0h/GTMdDghq6evVeAI/pkGGkNlk4nDCK2US2BEYYGYOQ2lFvgPvCxnSL2ZJoJKatQny5glSRfpCM6Tn8EIBZvW5DzGu68fU6tw49qtI0ejibAAAPLklEQVT+QfDDvIMrMNQ0LXcy5AzT0zy/OSRD0Jh4DU8DyNCC3qMJ9mWEj40LBd1dF15MCDSYlvIVYDveCxY8HTKMNH2IhsaRAfATl36aKXUdhCIw9XvktcygNRUXXg3fynrplf5TzLjz/KevJNrhpKgkiQd3KOZZ7wt8+ZUR2tFJKs/hUBvLIjxGBBC1PNo50WjJQEDlnOhmoTcXMC1mV0gdSXsByLq+xPpFYjQ7hVl2kiFZtHU+PTJ0f1IrhTXfnVWi3oHmdYqvDvYuoNoJb7xZKlQAn+gQc6a/Tml9hGV/UWPQlx+UnrH3DtPxp8mm+nIGdJKnR1SMpPItJdSz0M99hDEXa2sOxXJovWxTQ79JBos0QAAERdigx8LlML0BCmJO2NsI/A/q0MqdDK3zR73HozmI5Xr6YMpkGPUdi3aJRX872zyZCbEihYZwvoi7ELUjglQhutoX3Vex1bsLtQtb9lIP6RWKFgF2KY9n5KfX3GuUFJOJHtjRvgSIRy369ApbuUaXrAxNMStwhvmcxHotGeLhNTYqOhIjzqeQXlVvvDmGql9ewYl/W8+qNMXpfZd0XolTQB3zKZNhxALYLYV4MxBJ+S0JXMddw5t6MKdZth1fnUaIceXTVyHicprWZweJSuT/qV9Fg0YuXz3b2xu5Pl+GNpX3EA14/qNdaVqk8hqPGeKVXy8S4is41IAMBgzEei9t0DKhe0Qvr7roWFv6HCavaohJRzofs4ip5ArJJj3WzGGmSIaRFuQDUCV0VEKua4Nh4cdDpa0eOQcuo05YpXXP79uJSL1HduWKkEiPdVgdoXcS01groW8pJJ/xJUaX7Zp3rTuTdT7FlJ8c0dUYnQgsPzma9tMyDJIhoLHK3G9RVcLEEzQaoEnvdk8IBgMrjomPq5F2gXupSAkp0rTIMLJyerO0phyKUXG9l+k7UodlMBIZA/WDAZhhs6dLcICShOC8X8OUP3zCTkl9copj/RTnK88/aK7SDZSXF8CfIixe1rGi/VcNFjWTqI8ggwi6Z4cdAUMqsI0MlmqJIObw/s1X1Yzh6JfJh0OUtu+Rql/s2G1z7reSYE3TIkPYqealVGtYaN2W/negZeNKfamhtATkEMoQrJ1rpNA0SyJ/EcUpFyc6rghhe69iuWF1tWLjmB169CSKdX7sPDimZ0cAJCxL11mRpRdVz5YKFZfP6PVl4MvV4o4nUKPIYNXRlp6sheqproVk0H9IhnyJ3w3FZLC9faQpkmHiUaNSFI8DOhcofL8hvEkj8WvrWQdeDSrWl/fd2ktwQcmJeFakfFIKZ80CD37Dj434RBqsNK8I88gWzeA0kY7/dOVIvS8gWYkey+9Bri2D9tvTFzlS2Ak2Nm2EQj9uiMR/CQ3pa8oWuIvWGCo9oBFFpkeGkaFpNcaMnvpvoRWAwBjx75NgqsLRIeWAapT6MJL1qEjI0SX8pRk67Be14RCqyJBy8xBXhegm2Tm0FlKoZ1MaAbRO5C90+v82dyYLEtsgEBX9//9MDlYVDyRPcov70tO2xCYo0GJPTrkkbgFPyUQ6nddVhzVKjDl+Vz8DX1LtaXFxh/yY17cL4M/S5kp/NZ/8mg6/CqQ4oqs9tQTU9PrvDcjbeLog2PTmc9KmWB2Dm2xvKHS5mtWnvrBkyr4MHAsR1V6TbLwKRjk5WhZ70CvH/MKlEJEpuBTbQYIrUhynWmN/0cE/O3xq9a9xmjGafTycXcnFJR6Ct9lrE8b8Uxlf9JvbO1Csxed0+M0I08pA8S53laOGFM9rFUlqDz37XkLebaxY5aAyqsoe193JvLfa0qcM1VYMbC3dHI2zeF4yjZ0Z9uL1MfdvDt3DewSb20nf0pXjoINqbbf7poNsCnvwhHKAVr1qRDaWaCVbHEa9gTPgXWis/1PozEVaJ3gF5PiaDj/WbtpRTgsRQKutb5cEJc4ZHEa7ll1Wja+cnenx+K3gW4sBk2ZQ9I/SwsyBICtWHbDbQS1BBwhLltyBqQzolB6xn61eGxwe5fSKmKTh+dm8iXyct3ke5AZ3HTj5rmdXJvyGZe43Rjk603vLtBScTfj4Ze0p0Ede5s8m/DUdfhpc+9UlO5tQTx24rswitK3BCwptNF24v3EghiIHn2j853HfZPZhxshG4f4D5ZNLTtCIPhqrbRQWw0IefxXdPpHM835DvQ0Kl//HduLt8nzr6R/NCfdIuNSrPtzslO6v3qtQr1+FiZBN9pr6NLe4BslXdPjFduZCTKWdaAOm493K+CVpzzCMUq9QtbKkDHPsXgakI59Y63kJVSKPhv+uiVxdsz5EDZdfkLdZRYftIBcn7JRT+mPwuKPd+8SlT7Zv/60susei+F10EDiMKGmlu2guOdoMxmo2TzA3J83EUIWrglVNSj9WAubnm+cU7kM6/Co96ZDc8iCnWmqTLJDOtjYtmUytVqFGwS6QD7Ixq8zE0JU9UaBv8GTr5785P8kaGGU3yuGDfUSjxvHRw/66AwiJHE3TCY9yGU0xb6ll6p5p3nQwoGTXi9LGwa8RtIwFiqv3vc21dveT5qlfSxHT9mt9ToffPJO+aW8QroERAgejSo2VD49sNTY+dHRaS7hcRtBqTTxn1dsJRykrs9DIROcFBMmEbacxoLNlxwBMRFeG9AXc5CRr82iTtu3Ix8se6ETQw/ekg9u86aCMtzOOAU7dOkil50/kdwlA635e92pZsNHoCAB8hldyxaXPd3T40SHaHN22V2pRPySdwHl+OtGqtmHm6DrRYXeodBhnMDbQBb0zKS2t5hT2og+8rx0XhnA1o9LgBbIaArP1q9vU13PgRwgpMCTecy0q2bLOuw6NsXTv0VxcXPJSl4tzNpLZYt7lyxGY7M7sIIkAgrdB+4gOvzorzlscOKWLDVDa2V0nsYtuULBp1b/XcoQfZRf0Vu08A8Tp9irDDg6k2VyrJvTbYG2KQFub14V+9n5DlaUgfwIcNOaEPxTAkxgi6qLDEGadjqE+lT1LMXSbPA8ascpGc2nzr+41zpXBdekls/zPOvy8BJnacFurj3JFqrPEDN7mnEDgOR/Q/cBA50bU4eC3pYhWikwUUM0/ZcI1b3St5ZWM3M7el2yJZp1XQ3rYiQf1qjUMJXWbnDwjNkAit/2s26nDc4EOQnn4eUPktW4R3UpN0Chwr1MGt0/1D3/Nc3J8XuFLOvjNfUazFELCGS7O8i5rKRUT9ZLCIyvFbLMKmW8ZceE+f1/qSB++WyzD4uyySxSuQtW38qaOep82aCVeS8fPxXLk8P92MOpLX/LabwVxWfaiwzk52c+jHBK+fc7+NxAmy7bax54jC1TVwXEpxK/r39HhdwLxPsW5NzrOg2ZATv69eJ+/z3quC4rfcMaK5NyJhI6qTDYlB79NL7aMBcBZbVlYultFoF5l4kZ4sq5lIqDRTF5Ceq+gyLfnhHnIxc3INx2a4gCsY9WN2Yd9acSmxxttyYNB4mLEy3WWTNdK6UM6/E6wCwAW0WgHBvllpUKeJ9EANsGO33e5JbyrKp8VqkjLjBZnMtizAgbjeHlyq4CaP5itFHgWgMeyRQ91JzNXLARhOLsGArOCYdtq6XmKsrmzFuSuTHnXofqWPDlG/ylNMI5tskQyApzK3N793fapXeUyQ52NxKJACVt2QQ1/Tqy/o4Pf/k3nKGconol7D/3swqBMakjGFD+DQWnRqRYOCqjlufZmAwdP2Aj/Kc1u2ucp05LXdJhxDuJZ6NMWIBCU0K9IxnDqR47jwOQrnK5mnyK8bdWIz3G60JwIev0UZqtpRF09yuPdp8hWEGjDNj+ow88HszCBfH7WyU6P8wIVSrh/VinVn6nu7eR425FfIt67z4jsPJwThprfRCtFGAKn6vfo1oGxqKdCU9cfZJF8MWwCOUUnsMM8UWzfD6639wnOXYd25Hy9BNB005Ix26XpKmLZafba/tJneGVva/RYsfqJ4q/o8PMEEKjmrK2o3n7tgG70y1XKJ8vJ3Jx9LtmirxCxxltLKbfNvbBKJUO2Mm3UgokjyrW08yimt4s4U8FwyWvZlZ94mJRLRtvXrs8JzG+Cyg0Epw4Ifr9K9M/Pv0LoMgCITQOYeYar96m/3/jELmnhLR/T4eeNDoSa3ox9rDZN5EuOaQ60XUvlDB4YO/URb6PtumYMplzfoG2ZstnM8oyn6rDUF+4UrY8O8SVsoyCMRnshWcHpo06kBuY2teSItAaeLp0maEwd9r2c8rSuJFKrXXM3ycHIxEp55lNu2fB5fNRnXM61jGojqXxFh18NxqmcnpXPzQxf+0cFAVdRntK8BtVr6eQygYSZYqaXLUAhsLSh9Xo/G8YCn3IezJFwrN9aBgw+8ESbtM/WNf40nMIQ8wZn5L6A0PsOHXQPZajkk3MVniBc8zS/FdVLrVuZEU1+b5BeDbBKhxh0Ytjjgzr8NDnm8qqe/6otdD18EX7UNPdgbzzU0B686+k33dqO3KKz3DDLWuUsu48Tx6UmxM1H3m1gz4EQ9MlM5iAqzrWa1DMVjzfXnRa11XijYQ3mqevT0ghycTAM7E0H2WW0D/GzAxJ+5XFZl3Zfu1uin3u8ZINbzX9tumVtZvqeDr9EuuY9BfAeVyilUkL0seWkJUIry5Ch40YFYUoNtOd8QrQ2bbpt62NDVFsv97n5Du4sm5k34Sawa59Ws6KcJZ2zFwNy00eZlLQ7kWOtMUzntVcdYIP+95CxtSEdyZm9L24XygpgCjznp6Y/db+1ZFm8SPc7OjhD9PSCqFjp//6YCoQmm3LHEDz7z0d+eB1KmkM0rboMWikaMS+uC1KFwKdI5Bys7ONTwLOXERMZ7mIfDEIf5z1DmHbiICJTRCMgE0QF5h86nMY7P900zMTg1Zib0eGUWnlMLzOHeYyVa9OisxYwfFOHn/7zCksmTSQfh6mNupvcEo0oKn2bDvQOtLHwdOqWkdLt+oNGCi49OAQBs2gCRDbrLF4T9bt9KsMUhfNv3obx5+GxME9mycDN6PTcL/7QoRmrbDEzOmmyDp+fPmAblMZNrgBaiLejEo+B+Wx4wwST/Y4OP092CdxbAMmVvo7DaJv+M0hRKFf+e9oGjJpz2zmnU8SwBOkpCJhJmNlIm4EWaBfjHoJl9m3pBlanDi1TTf0QCMMWXUbIM/tPHY7UghJRMkzz/YXGfyI1g3cNh3rr+B+Yf0yHfwAjBO4Lyccm/wAAAABJRU5ErkJggg=="},{"id":"DigitalGlobe-Standard","name":"DigitalGlobe Standard Imagery","type":"tms","template":"https://{switch:a,b,c}.tiles.mapbox.com/v4/digitalglobe.0a8e44ba/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqM293Y3Y5ZjAwaWgycW55ZXFncHk0a3QifQ.6Kprj_J4oDmXqV97RricwA","scaleExtent":[0,19],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","default":true,"description":"Standard DigitalGlobe satellite imagery.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMQAAADECAYAAADApo5rAAAgAElEQVR4nMy9a7Bl2VEm9uU5595bt6puvd9dVa1+6k3rgRCSQLKMEDCBAHsEGptAGE948Bgz88Nhw0w4bBzjmBl7HDE2EzM4PGZgAIMNNkYEDKDBIARIAoQeLSG1uumu7uqq7nq/bt1b9738Y6/M/DL32vdWYzw6u6PrnLP2Wrkyc2V+meux95WFd31fAQR6FdRfRYuF7ujvAhSpdQsgUusLSikQ6e6hfkcpKOJ9AIBo/VBaINRfqd8jd17Lf8HqgspCy8pm6K0Km4pNCYUqimQukHrs/mn1kcuoi979QNsGo02rRNVXjTGf3e9ePRoj2bZe/Oz1a+0j41omLR53+vwqyzBqDoR9casohe6WTmrroPiHVKcA3BkgYgMsXN9csXT3itBNN+lKDp37CUSZLahKIPrGp1FGIQYLeaBIdWhSQnGmjIoqXukYYIQr4IoXCfVPl8oQnaEow/qBUoZl0KZhHKoM3QAL3S9WjwGro+P1CtHLn8a7lhMfYgXFxqtU+mx83m0JKpsWGUadSZCFEdNqHGrodk+otoj9dmSQrhK5paKx+5WQkmpLikjqG2agQrwpkmQEQHHe2AZL11c22FJxxepKsahVTCvFBpadjEe4pHtqyPpbqtu5casuitdXPs2r6XNABuOwqB7EeFMDLUX5T9G4Wg3zqarOZd0n91VcBi1HB2gWu4WjqttXMGiZPhlGqKFGUFCKCyAiHpoCDyV0CL1vdat5mGEWQ0o1GTKrDvOLO5wyZ3XFfN946OxCjK7dFa/p5WpYETn0rnQj6b/pm1LreCjkky6Dyizqt8Y3NJDaIIoAUgqhktQ2xXkWgXDvso0M4nX0vusZNeIqx8S/RnCAxpiN1cdd6Qn15WMSy9lQAv8SywKETJkMk5hjVRhns0ioChLUWfLymJu5ZCWTMWQWiFDmKNRAnaT+o4KZaTBzAsCpIJp48Win6Z71UarlKiB4lLDhU4dlRDNnrTWlmMyayypN0xWlj2Te1BOXlV55loGCB1AEnnGqx1XaharTgMd8Xex3Yd2bIgsNIkd3Zlvp+fxS4dZl6I/rNMkwcu+IA9NLkY2MG4Xxqy0FYaA6BZFwxjQRkxgzDHlpzAOuEGOOIqlOjxUx5HUfLarnwEPEMUIym8go0zQIhdsb/Ft/wTlrbsCmnl2CuShlWIYuChVjS5iizduU7443Q0YNYdXZu2o+mKZ7YVmE+CpG3/otfSlQXIZSaXCEmDYZRoZVRf9hB+w80OYTNFg296Q2yrCFd2png671henVT8rVJd9TmpQWmYqkjbU6Go5Z8b4k/LKQa23E5dGvqkDTDzwkB9rcR5WNUjPWSXFzCXqSUjq5t5FB5xYEZZZmaWTLE0udbzEGampDawrk28XLRdOSKoP4yo5Uw7ZITuUC1R8h+BTKYKtMKkkpahQgb4rLjm4QnYGqpxvcWhsaPpvEqNc7dGqELKpFSih4IspCRkT2ZVZH1IhIpVBkMqJdiFXa6mxhibhEgCqmJ5gzMYqXGgVsUqd9WB4pKFJCVGFJTIaqVNVZUwYwcKH+Fr8tcOmMp84xi8lF4FV1qfM+BzafT6LWs/FnHmiQOHXuutE2KoMvVkyTDKMSDN4N33cB1IPcpW0gCQn4N4qia/XsoqHKL7M581oPaW4c7mgWlUqxfsycKFTHeYaVOu8WSqSmZVrbhikglcGOMSz24askhfrs2nB+avMY0g3zWSyOaAPPi/uxkgyFFV89t6gMjmqdsYlYWqxjY3pQjy/eq42H9ekg5cjqJQrVtjonJcmPYEM2J5syGUYRo/qmFASAV+N1cSgSFL4PsrPCTcElTFZv6GpXCDpmbtFhlIYqMfCMzoEUDTxgEYxBEUNqyiaOOEazGMq7IzJzTK/v0DbxE6mG4sut+VI0DMg6IIONiVYW3aPxSMLqdYMszrJryhkm3hQ9LdoTYLJh6Vexwff83xYTGFegwDBdMozisPiASs9SYzWhQVPyERWJxwaDlnblcsDnC7nfZI0c/qIRuw8VQ66WECHOOF3h+s4k79h0BbTsB5UzqjnL7OimDFbdpVUM5mBIhhYIUG91jNjJ8yyk2DiE4RbltY+ongsGwRAm10a+OOFk5NMqwygyuY0TmIwlerkEetYDCxrNqLImbQQw9Gv3Hipq2NXvITwCKGqw3LqDXRRDsk4IM2jaLbfAbJM6Rxb3Tv9lfIU7ceIehyajq0vOSdiQDApMEXQKdFM0c6a0HECkjkMySbMXDvV8n1d6SC8+cTK9NuNgBbEyhTKMAAR0yrt5bOh+fqREaIeGP0Vm6Q94ECcJV0os5VyzytIJ5hl//xSU/6tteMXfB6nUsOwrRVJ14ImMt2N9eE+KVjqgJEN1Nkc1501qOqD27BtuQm2K67UgGlWSgcvVSHgu6I7E+XgloTNKINSzjnuLJUzH2WmOMKcKTRkqSEyhDJPKghOtlX0y7MR0ct1tu9OGCC8poMTJqtIA7ECf1hfycFUSlBNykpBiwI1KlIdKz42sJnSlqkngxk8TNRRXjq4C2dyuis9Xgdkv2NhNbwWkbFqxA+lSvF8bDLYLEK/meEMyIPZJ48TpikCoHf2GL5Z0KYeYg3fD6vf4CnagSGv5ry5FU59hMk1gS4qdFhkmmiJ4B13rEoh42NKczp0BPriiNWB1IWREDSYy/dI1NCq+XOdKcxRxLWuZGxn3VZXFDieaNhVXoonEjuIDqW3jwIRRNd2oUUBTA9aMpD6MHsU06q+r05ehN80Lk7ioK0/FGJ2ZHnenoMjjg6BzIZ2bBnjcuD7zZW3b0eWrLcOo1I51EIq4Y5TCDWH/x3CoaFaoAoECexYZta1G8ESp1ChSnBaZMBSS2U+L1SeH5rbkqFFvDWcoZJwqOzm+NstoZgfPDNW5K4kIWmnyGR2PBLX/kvodkqHE76IRmnL5YCwl9uX0qQ316X0orOvvalwl0Tb5uu/OB3oOzuM0TTJMzJDrgHW8q3cxQXY8CUKyxxeUcFjPxjVHhhbipggTCEgXxzR6ZMTkf912I6VSFcHHVTzb0xUjR6EYJt1xWmkjy6e5a754taSjI2ZF8QiN1yWw68sgPAg+dlL54fSMQ2Bh/iTYh6vcEIpQXulqDKzMBTWpjJnxMA5VR0L1p0SGUVjXr0ZJm8gKvh1fZNwaGbRO1IdE5uBe3ZtwgYRtas/BQFR1hOjR6xEmyZkOO5A5jRq4Cql1FdmpXx8TdT93Q04PRPlKl9HT9Eg6hMoRx/pv6KKX+lX5ewsTia9sK1wQ+lJ65rwNGRRxVX5C8yBDQwdBNp0fTZEMI5+EOsfOrA5AqeWOZiV80vhz7s36qRZVQA4n1huCYyK3C/rkc3UdTa5j6V9r74F0o6mWsiyqwNin7266VzqPHDqJrvhCxaCfD5T3mjRAtvCXCmIZg3oT72wYLcsDbPyCEWZeqzUWBSIzAGfE7K3Rl+tNpk6GkU4EAfXQevCKiOlqfqE1ehWMHSmuDFX9FAqKhdA2y6TGWb3bEKCzL6vTob/fK+m3nXy1eVB0MQdyGgE9MUmIzwos6bvzTu21TOrxNfOHfqQyPgY81lPVTqghGdhYfKmbeVZhQYPQl6krCK1DX7pnEOYEKqNUYpryhlUdIXouT9z0nS4ZRqUaQuibBSNezMq1I3o8zQzMmGX0zIwkQzUjU8VGYYLnp/xMuB/Wv02WJbZlhWnqh9SWUsJOLHcudlTSq7djnjhFrPcTplg9k0sSbcg2MqheiKSlLamepEmnokkYJ74dx9ZWdUrdrymBUlsfPQajjUyjDCPPodnAkbxYx6pGEsVSRgcgGD0vKVrHAlrGdJwtBou8LR8PSjgjOnFFdR4x46WmVR/eXidofOSsOMlqs+ogQn11ii1Eu1iY8s/urJOOJaVt6lyVX2G+jF4ylDTRHpTBQ4mnGyZ/to40nhV4er6pdAmEijpy/S2apjqxRneJttlmNvLpkmGkDGjeTOAXPiv29dmixE/YWC3C6OS0sxZFWkZNLevSbw6vsO9k2jBjJmczUOI0g0jYRDilN0pSKq8qktLU1a9uIsby1whEOpGKgJL5B3yiXWhlSu/RDwcEFd3ptGTwianSIR6pbdz3MYoISQrpP0d0j4wlTn5LvMdAp+mvH8UGRcw4vtMiw0jqAEk1om7JVIeluoE2AJ1R4vFmcOPwXu8xoheNHooCInasVxT1a8QIKzcmoLj1JxTwaEVr/6QY0jvpz4TrnBLFxoAn1CYD1K4L0Sr0DEXplmNpYqf9AtJ41qLmtpoOEK8UfJsyFK5Ao2uRjuVXsGJoSemnRd00fnEJXaJRMqrniybL4b6O+xTKMPKQxSZvFkffNa0q4GdfC+gTBNrFBzEwD0UNr1MfCqtlvoPMwUIdSesrWxpZzEGoXzVcR5Dq6IRaira2Np4XDkpdkoWQPLobXWz5Lk7soyOaMwt9NyeJ0ckjriZeMihDb9OQZeD5DhTcQDpNR28YKUrUUbhYPYy8yjvivaa3aLsplGESYAjKIFm1OUUnQVe9cwodYAhoj6gyKR2tOJjuqRL6Ux6Ll9gEUoKee5uAhMwdAhNNZY77LtqONeSbakX7oPDMRyvCBqOpwXWoBh/2F1QXLR0oLeXBb7j2ZUgGBzGmxX1wvZ4e69h0m1yk/WoCvGcUj6TY4JEKq7FqyiiIdYmG/RYnMS0y+MZcHYnOMWtoV19wCHAES14WpzbulTx54V1dUyDrM+XGcYUGFiqE7nsIlfCKF4cRNC5R9dc6XT8BqTMf1Fblstq0mlHUEYKiCVqKn6lFGPhKl6KK7CBD1FMCNdJ/0AdTEJcb7MBE3iISAZeWR4rKfyppoHnxwqmTYWTVhb1PjZWbDoyLtVXGggc5AylF4HsepFibEtpUqKTyaJgx4YYjTXXcODllXXnMZBeNS50g1GLmqW0htri/KkOvWYrMgTnlIoFPlqEHwaaugjQE/bHbLo3I/Aw5JBuojk+jGrfvrUROmQwjHizDLhGfqWcmaweWsqWOdKy7ex4JIrPRadz2KCIAPYVsf5G3MT27GySgPF7MsIMzs1wKFiyPokgH9dVXnYe0xeQfNtGMqBd0NSB6lsFCTykRmgldUSftnlmW2FblilbbY9159Dp5JznS074rR5YmUkpVpk+GiaU7EpevSs3hLa9VJvUbAajnA95JXiLzTS06chuciaAQ/bmHy196xmQQbLLAJruJbeO3lQbZ1xKL2JDtd2Y5kbJ8Wagwy2aWQQ7UAoPET4gOpXWT6SQttpJnpaOG1Uo7LK2h/lTHNvbUyLEzGCA4onPfUyLDSOoSoR67tYsMWgBbetXVFHVIB8pmTEqCed+mo0rY7ZcMT6lm+dWhk8N1VZIismFltAi3KZplvnPkUpmDszjS9M7daEN1RpIxfOf+e/f7MvSuHs8llvMKFw8EA1RJ9cN9GgyVOfdpPJMiVU9KPwHwtMhgz1T31t8pl+UVraIELM1wx+z6VCeKhtmtODkjfsbJETLn3bWUFBIjFkcBTifiUpySLCa8v7GyrixVBTt6kFDZESyVjKtQOsiuq+Kf8HEYBI5kG8YXO31DBq4fELLUPRXTiwth53rI2YbAoYTvRN/KxAGtqMwtRyAa+j28WnI6ZBgVtXjx5c2wTAp3LIsQqN5tRwzMghEkpN8MEF0jPz3rfYl3wiRp8qU2oqtL5hPVUPRepm6IzeG3OqIeAbC+WAoybr5v+xXhUVoHHMeN6Jw5jQS19Rk5bE4SJtJZBgJEPUtmTiQqG92nurrzHiJrMOaOZ4HLEPZKbFGjFqlta66vv3WsGCjD9+mSYeSTwaLwH84A+WDwD/UuX/ktwYI8ghiCZ0RzK3aDtifwJTJODNguehXIJ1pQTzFZbU+lKkaRwXfOWTAyTFYc8lyoIQPTUTLkpMYvXyWVKaspP95WBtMDkxG3RENCEsxoIfKl/h1AMSM98x/R3dpQ2uLgEA20ycOUyDCyAGHeFVFL2TdWFJqqE+QdVN9ijx3ZikKt23qAhyJiaktHd/VhCiNVopUab4kYrQKECSzT4r7ZUVRxvNLBY9jHD6sfIDAPQBqgFhkLBYMylL7uMkiYHCCDdecKvFi+rf9XfbJT9mQtbjucPzMdTgHDK2amS4aRepTzUpHJA4a3ScR6E3k2mEqH1+/dJwzCqePqSNy8oomFR+Yk8ZatU+h7trQwea7/G29NqwQpNtZTcZx4od3yGD1CXUFPBmG+8tWSgVILNzquS0wGI/BBD/oGnB4ciLrhChoN9bxIGJ6TgcSde9fldMkw4pTDowXgB4zgKJyXswKyqjLEfpqSgsJUcBeiM8bYzq2HvVUFSBAk6TfxY2RKUkQSQYyFDOE9pgJbmd14yM+bFNLFkM+1+OqQdECGnIZZCpn4FlJnKu+fHnUG7IAkMRwWHlywaLBZhbn+gMzTIEO3U615NwoxI2TjbojBZhIqUwjoyV9SoUWb0k1/g/Fk+k3kMDZjGy3XlaPqxxDEoxBm2wWmg6rxcLKUaPX7oAiokUnbSN3crLoXk82PnvQUY8qiY/IiO8rg7VWxcTLeHARKU/LqjOrV5Jfcno7fSywP85xalFIQ02VzafqrLMOoupEnGgXwZa4Y612ubLnsvbWtGkr67OrSQS4A/uggSc1OXK1BI5f7nRtHXNkofhYLdTxsblOYTZMZVNY/8yJNJOrGWnXEh9Iqz1VhFjirEcRz+j6oLoA6DkfXhgzspUX1qTzQ2CnvOvDqXToWDYSNfWjfrvLQQuh/Lub5nQFX8aCu6DpFMozsL3gqkfAjrKJbWaQCtV9CUjZ+ekbb0NStNxpn7Mr2IFLqIxX6zcNjb66wMN8RN8geLHX3I/gUioyRryy+fudTluavqY4PrETHVSStHpSf5WjLoJbFXaR2dDssNBhYcIUkl2IFg4Hpg1GoUFuXwdLWLEPob7pkGPHNXjiPEFsdmB7sIBE6XhxJGWW1zyBZNYieIL3Y6Chb2DmgfTCK+KOb3gcp0pSUFMh6ykiXVNFL5/hSxIOjWS+UpwbSE5d1RKjYkMEm1tq35mbqnKD+C53b0fEgtAzyljrONUo1ZWD0Ntm1P7pX8rJ1ROtpk2FkD1FUVFKj5/r8Q9GeD0VZiOtxxZ+NSyOH0tD+w71i/bqDM2wXBEMEbE7Eodj3NRCNsGXYpIPsIHl+DfCAaQdep3kgL3Tkn81B20YGizShWUJbvc8gwaz0nM2dTp2xy/Wpk2CEhPAlK9SQjOZaDpp23m2KZBjxfQD2HKz2JkW3n+p3YVruOBYAijqIxNQhyZmPJbgTqkEJ2YLuQDf0NbBKUYICB/TdNG7c1xXjI4cYBHmZ5QAbDVQLObMWbyNDqQgc0FJlqIah38NCAUqilx7cIb0rOxne/BxXR7szm7hRanUVbIsnq/6g1XTJMOpNSETozX3xpKuegAVNTIM8OmFS6YQNPFpA79yQLgeUAl6CtajYq6sMdL8La5J9zWQurhUjlTyWvvPgNaMBj7jxTcNT+zGwoDHvGOI+QTfrPeW7lEEZnLYWCoIe2Q1DaPN6hesVgzJLny3a1ojrWCLGp4534I/SYZtcSycDR/Bpk2ESxgHKt1uUljmw5eMS8Lpq5DQhFPUcuuydqBw2mSSFQJtIpuhiP4lPb0+/RFenYpiNEzZHYT5saAQp4tncKIFIEAB9HdpgWIiVrBbYkfH0eK7TSP0Ui9EU9fisFh+zr7qgMTKg0TEjz9WJe++wJhmc/7kEehpOXAZjV5QCjQd59DTJMCoiYW7byeKRQZ9VJV7JoPTgFC2FshakDq4RrrymP5Log0zr7wUWZv12MVRBQT0tqf/3nanniLUPjVy9B5LYUVgfZJUWZun/EL1IUYVpW//0q1R61pWfPA4MDMhg/XC0Cs5OTw1SdM+TyVL1FZ5TKToZJZ6FAIfmd5pHM99NGeKLkCKfUyLDKCjXWQUnS0UZJvn8ZCKi1yeF8F/q7ISqTIV8EMGa3UkIUVkIQ1AVipDY0i3d4whsU3iufHUeHerASXY8sNEqP/5uHpqAE5xTWhnb0shI6MaaSh6QIRkYnWmlIJgd6aEYSOnNrm04GmM4QjoVI03znFrRuuXnalyG5pyMZJ02GUaWtgSOg0UYAkuwXlAuaJybBoSplK6kt3zGvlgrWmsp5CwJPah/NYze3kIpMfIZi65cD6FkyJUvo+0e7H3mNrmfojKgEXXyEqAPSMt2WlfYM+EUTPlVVLVxc3bcWFwGm0sR+DB7irYuX1/XjuTZSULFXptpk6H7+xCS+kj0bE6gPznH3elqGT8LxUbvXbnBJuNS+fgzf7c2vRtEt9WY7D/MIXSwwNEg1u9dxGQ8/kw0Ut/SEmw7GXIdGsTm+Z4Buj1aua6kgh7thm5aHYb7A31+lWWoZ5mk37ZGBAH8fI5ZZAPLCqInZaVIHxE03bJq4nR0ky8YHD9uamhANDV6iNcNPLEMneDhXj7dG1CiFQkSOaMnhFitq6T/h8qH6lhISZ8ptS0DiBhPEmxfp3meSOsWqltiu4DIOUoy31MmQ3d0QyJvHWPwyCC6/+DWoRtpsT4o1A3FLWdMArMS6nCkUOZKoWcwFMBT6BOG2awIlcmQiKIAWilWLmgolsUiffhDV8k5JP0PKqfv/LjooAy9VSd+ei894iqx3HhSEEn+a1rkFIhTVdMjrRJSNhD5o5Q8dCJTJ4O9l8n5rwY5AG9qxGE7nI23MmDg5jI0nKSfTlhksN/FFMe2bO3DBKt3sxmZO290BPA+ksxJrmi09IBLi746nCAsDOx4tdKFIRnIEWn1PVTRFI1XbYykvmAipzyFnnwmskENJStFDdZaBgRucB+/TIkMtlOt8xld+rNXwMONVjuQXF58a96cApRugVdq/IENV0oxzo21sPpVggaNVtGmSfHKz+CAMDz7+ZhCfXTtVG5SnGq4PubqJyi5L4mpHcKXZjpV8g+mNSBDDxjS6HCEiZtaSpfRN3ZvGiL75NU0f7dv1bMZLK8IMRG4AYogczMtMoxCWKY3aWRUir4Ub9qafqClN3XrnY6YO0/xbyWke4qytthjYU7ApDIChzdsZ3Qt9BkmVvREV8vYggLExiIiV+6LB0mNoh0xJNlBAIMBGRgYepfRct7D3kztg3dzDY1zfqD8FC6i6GdddZXSUKrQQQe2ejRlMozoOB2UPR7fHBUKw14spBDEX4WMprpEjym6b/MF91xbbWoZnHKoLAi1oWXgoJjC7ROsULXQTwPS1P87A6AHi7TcJvrUlg09d5SNQiF2SIa8UsLOyZNCs5+E1NQuGG++1Cgk3y6RDwsJjHguQ3x0tzEPnQIZRuAOdFVJq5rHuRdLdf94jJeF8+MYPMvvHXVgpFbjUSOGb7LEpbzUjuobf/W/YDQWYViBDT4k3S+JRsspSR47IsD9CfqTdTMS/p14DDg1IAMqaATVkjHmCWsDcfubioSabIyBFjPMekD/oj5DZOQJ8xTJ4KddOXSIGzpPZEXLKxO8TR5PfLqB8GZNb23fGE1oaQNfFUZKbMzLo0FZe61LqBA2+9AwPpoLwdt2MsRB8zCgfXLo0DQxh4cUYbVAfboketZ8QAbA/o6CAxfP50rsg4U3HZdYbmzpuCVQBAKKN7A4ysZ1mBYZ6zTJMFIi9clmvymehXFOrl4eUD84np8s9MN5yZh6Rk1LaFxHyZvx5a35fl0WOKRE1VF1IzLkO+KEFLOcRm2lDhQMPDHBkdRoFOvbAxohfiBBgKH1sY0MUHQV7wOUOiQdFPhvT1EZhb1/G30RhAmO+H1jg4ytUB1fDSrOByN1iBDTIUN9c5+Ews7+tFMfM7aFkAKZcw6sN3NRAMdin/FZgELAoF+ov14kQZhQRfQv8Tsty4W5S7jvz2Ko0YpGsjTYQRZDsDq49of7GMG0n6QTcqawJKw0WzJA7aXKIFSoxGwxI93TdCQMo9IpJoIpgfzdHFnIAcz4VReK9PDHCUj1maVpkWEU6NUOunuMSuQU6mgl/SZGfQlMgvMIE9I+SupLUVC92FCE+kS6tB4J2clPCmODU4O2uQ7xr8CeQ28IWR09jmqdLDxA0fHYiIvRhB2DMefUtmE+MiCDsk23HBAqoGlBKfZL7SU4GhSX6aEd5V95DYNOjxwnnoQGQcE5bt6hd02LDHVjjislgyPgDVmCxApWR9iYK+2A2J0xhIN5GTIKIy7YPkh5JTbolcHbV74MJeBlIa0D8SuUxjEd0wNN3uH8NnlACgCipwNKiAZhNS5EiG1kqMoJ8z9VPjoDcbDQZ0OKO2HvT/4ouDAKq2YqOIkbe5in8XcGlIDMDW+YIhlGoCsgedfMaOmR8K6tDpojMz8zUYqYUKIMJ4O2VSXusSgWpCMADYdpT+JB6BJJ9xE1V0BFIDdye8DEcSnwwIYb6XBHSaeUAjKSGm/aRp2V+MkyqO96uaJgalDQjU4SwfXI9dCoJ4Gqv9jY9ocZEa2NITm1zdFt2mSYpGbqP7UCISBAE2RRkHSWS56wVkqKnFo/5cCo5YrUliIU9efqjmoc1N7QXdubAYPaWMfejhyOZfDl2u5XRGcfAG/o/bEM7sk6Qq7H2ZkJ9szvwu5ds9g1N4tdszOYnUwwOzPBaCwYjwJGYWNjE+ubm1hb38Dq6jrura1j6d4KFpdWsLG5GfVp6VfUc6k89PRpoOPgIqEdbEGjO/NWaMC0H9ZHGl8CNNNv/Wa0s018lWWYlIryMUWR+uyDBCQNTqGVzUkqNzRBNgWExyWpPdlO76ivsD87j2ZmMejYXMAcgJSl69zCfamm9Cg7O0vlzZ0J/pRfRXDlpXfmiAZHRLBv724cP7wfxw/tx9GD+3Dy6EGcPn4Yxw/tx7FD+3Fo317sX9iN/Xt3Y25mBrMzY0qdgOWVNSzdW8Htu8u4fmsRV27ewYXLN/D8S1dw8coNvHT1Ji5cuY5rNxexubkJc9IG6LCTmj7JgS2iV7KCoAIAACAASURBVB2oYal90bE7T4fpOx/lsYd1qo34imUPMxOvkZd/4zLsfdeHLbiQL8IP70kz7cvOHRA6NTC8TOhRyEj1d6c/RliiQ5PgZirauhKjtixsYQsRaTTKhZDAaK/ao3K6PRoJzp48gtc/cgaPnT2Bhx44jjPHD+P08UM4eeQg9u2ZDwPJ+zosp17haAj9LgW4fnsRL7x8Fc9duIKnnr+IJ595AX/8xWdx685dOOAwaKVPICrS9JH0m9tU2iGlS2qygc3loH45umhGwOVfBRlk4V0fpiBAiGn0C6UN6TGMYLcaUeC5PN8zhKUb7rbGYzA0oK/MjO5wdGo5I3kjNBqG28EZaFAyz+at3Lj7MR6P8ODJI/j6r3kcb3/Do3j07AmcPnYYxw7tw+5dc1V1ET25fxN1B0cZai8iWLq3ipev3sTT51/G7/3pl/Cbn/gczl28Qipgvesw96zYPxuo47UJGJDGK9VseESjfm7t9A3h/w3JIAvv+nBx4s5yvrhZZIGDUGJLo4b06wywuKOqeqhjsvEmYGOgMrqwg7RCzsA48qrU/PwcvvUdb8Jf+cY344nHH8Th/QvYv3c3ZibjQUPOBs9XdoTtIsVQm61ScHtxGecvXcNv/OFn8bO/9nG8ePl6xZN6CM5S4ipUAoy88hbycdYPkCJB/g4Dku4OWViKEHG+Z0qzMSvW5v9fGWqEiA9ihGO2wYu6zpv2QxHO+gopUk1VdAWK65NDo3q9T40d4XT1Slj5QcjOsz31YqUysYwAKVKxtshhxqMR5nfN4uEHjuM73/u1+ND734ljB/djZjLGaCRxIAau7VKkncq0vNVP6/fG5iZeunoTP/l//w5+9tc/jpt3lrC1teUyqYY5MrPOSA0Y1GWqn0Gr9YlS3+aSaIbyRr9AGq+/fBlsDmHi0LyhKLWC6DCcf3VuHUBB7+mAhs2PAaMxupw7Bp5SYBwwulC34bWGVA0gag9swczMBKePH8YTjz2ID37z1+Pf+trXYd+e3YP9b5WC5XurWF5Zw73VNayur2N9fQPrG5vY3Nqq41gwGo0wHo0wOzPB3OwM5udmsXd+Drvn52y1qSVnC8CGHEivT3z+K/iHP/UR/OmXn8Pi0r0eLQMVS1EKJCILoW9SbQI+vhmzhTgm8WgPT3xbGYWCWD+P+MuUQRbe+WENSKFG6LKUupFRzYkDB/OqdTHUKRHP34fK0PiO9r0mOmcmGBG0Ye67tpuZmeDRMyfwjq95HP/Ov/02fN0bHsP83GzPIDc2t3D99iIuXbuFKzdu4/L123j+pat46eoNvHz9Fq7fWsStxSXcuXsPK2vr2CrdxuRcdYQDC3tw7NB+nDh8AK86dRSvOnUUZ44fxgPHD+HBk0dDnzmNGrpa6dWl67fwz3/5d/BL//qTOH/pGspWhTx7e51RjspS8Kv3THNCOuf0Q42jVOMWpjk0NH1Dh1umy2vOwznEX54MXcrkHLgXVqE8ykUUyBGj8SI6kiudVcrGTLQH07eck21ztRyxE0uRIwKNTqK0zWQ8wmNnT+J9b38j3vf2N+IdX/M45mZnOlXWwdjcKjh38TK+8Mx5PPPiJTz74iWcu3gFL16+jsvXb2Nza6sOqLj6ydHDipnyaf2PceroATx65iSeePxBvPV1D+Mtr3kYp44dhCA6wk6rVXnecmfpHn7zDz+Hf/ZLv4Unnz6Pjc1NbDfPy7qJem4vYoTFjWTn3c+G8de+JBuSB+qQ6TCImpb/EmToJtWJ78yurdX2cva2UnwuFFFqO0QLMvLEqVWhWZAhvk28Nf9hMiePHsR3v+/r8a3vfBPe+NhZWyYFgK2tgpev3cQffu4pfPILz+Arz7+E51+6iis3bmNtfQNu3cLCpDSsfrMBasjg4Rbj0Rinjx/C6x4+jfe+7Q34wLvfgpNHD/UcY7srg8zq+gb++IvP4L/957+MP/7in3fzCqAPSjx+5lhWUMXNluogGRxf0yC1tpbNAGbk0QBLpVU31uj1kwTzfyky0KS6VjBeQtyAu0M1dAFjH9WtocvCGjOfoEIVELSZlBK9D70osZ0ftICoNyBdpZEI/uo3vR1/44Pvw+MPnsL+vbut6dZWwWeeOodf/b1P49kXL2EyGWN+bhazMzNY2D2HmZkJNje3sLh8D9duLuLFy9fwzPlLWFpejaGoxWwzYvbLRiLYv7Abj589iR/4zvfiQ+9/Z5jIA20HGUqxNja38PQLL+GH/sFP4k+/9Fy7X/2itqF2YmKk1ZzGJDbMDXPUCJNgpHFNWYMSbNlEa5L8F5RBFt75fV13Tafrp0mWbljwYzQgL4crI55NYg9XZiUpp4E6Gk5b9bEDraDI2n+tOzszwRsfPYv//Pu/A+9+y2uxe34uoO+txSV8+dxFjEcjPPTAMczNTDAajcwYdUe2VHm3tgq2trawsrqOL527gI99+s/wrz/1JJ67eAX3VtY8lRLeRaUJp90D6dRlEAC75mbxTW9/I/7e3/wQHjx5BJPJuBephybeXAYAz128gu/9u/8TvnzuooFprBdMQG0IoGHs3SNVN8A70WzxqcPPu9+ASNxLslSJMpJWuv1KZLCUycg3vI/2ru2bSh3cIgFFW2BULVUCNFnvXQyozTmE9g7oHzgcCAm98pnJGA+fPo7v+eZ34Ps/8B4cO7Q/IO2wctvLniyv0tBrdW0dn3ryafzMr/8+PvH5r+DStVudYzSvFC0BhOU7uh49cwI/8gPfiW9955vCDjj3v90ycKmT1s98+Rz+03/4k/jScxeo36jP3jywkSol7uOEWwZ4sQaZULJikXbV1oQx2Ncrk2E8d/aJH+tuCd3XyQ1beOeNlgeKE9FORGJ7neToPN2VUw07CBKVUZSuFuv3hlY6e5EgvIfLyijB1aEDC/j2b3wLfvQHvgsffN/XY+/uXY72acBaZVreQlytz/fGoxEePHUU3/7ut+LR0yewvLKKa7cWcW91NcqeE2nOvZMMgODGnbv49Jeeg4jg0TMnsXvXbBiPIV6VX/199OACjh7ch888dQ637y4bDx7FdOxKHA8ethAFKmwGJFe+ksNXsOOIyRmCITjfB0fRWD/y9cplMIfo2rulK/2eoREdpSK1vjuP/nYmwiD1jIlWAKpQjCw8iDDFMj30eHShI9Ovf+QM/ta/9234oQ99C1770OlgwEo7G8/a+gaWllewvLKGra2Cydg34vjiti0nGo1GeOTMCXz9Gx/Dnvk5vHjpOm4tLpsxdYsIrJPSBwX9rIh7d3kFf/bsi9jc2sIbHj2D+bnZZqTIcvHneDzGyaMHsbq+ji88cx6ra+s07Ix89Z9WxNFqbJSA20ArfaAUyCe2DgpFCJihZbU+20Y2bOLplcoge9/1YTrl7KFZiu49sAN5wpSdWZsbhTpgzhDcwNsZgNfJ93JG1cqwBrIuvTe/axZ/5RvejO//wHvwDW96DcZj3/jiiefa+gaeu3gFT527iOcuXsFLV2/g5p0lrK6vo2wVTCZj7J3fhRNHDuB1D5/G217/KM6eONx0qtal9xaX7uGjn3oS//1PfwRfeeElbG01ji6wXKQXB0q/eWj/An7wg+/Df/Z9H8DMZNzjY2gjj/l67sJl/J1/8vP46Cef9JQu9NtaJOEUBcjGYbOAEElq9CuAsIBiHXkDjSCmGonGF/gB4goU2d19yjDpjLjUkAR/BqAnaxTcwSoyn49V8CDElIeYM8H7/TgRroOe0uywRzim3dU5fmQ//sa/+z78tW95J04dPYTRKKJmKQVfPncRv/WJz+H3P/sULl65gTtL97C4vIJ7K6vY2NwKChYRzM/NYP/e3Thx5CDe/ZbX4nu/7Rvw6ledMnbz+j+XAcC+vbvx7e9+K/btmcff/kc/hYuXb9DgkLwWqt0INHr62Auu317ET/zSR/HQA8fwofe/c7DfIScBgAdPHcWHv/09+LNnL+D8pWuuR+WKkY9Qmz/8e7UpHj7L+CSIpjJA55jqLNq3RhDEVE/nrTDeiqeYIRLdvww+qQ4cgwinAaKzSCkyordEHATevj77Qet3ITQISqbvaixaPh6N8IZHTuO//I/+Kt7zta/H3Iw/D7WxuYVbi0v4vT/9Ev63f/X7+PzTL+Du8gpW1zfMQLbLu0Eyzc5McOb4Yfwn3/Mt+J73v2PwiHc3HtEIN7e28Nt/9AV879/9J1hbX6/jMiCk8mAIFysUAU4fO4Rf+Ad/G088/uC2c4fWZ6eXTfwX/+PP4Wd+7eNY29iMOg1RQNmrWYOBXFcqPQHiOSU7hZGE7D0SUO/nyTk48hi9hORQgL9/GWwOYcXqupa7SuycvFeXZbsJc2RSEjM0JAE5OGJp1CxUbnTEnpOq9+MhsI5lH+Ddu2bxgfe8Ff/07/x1vOW1D2My7k6grq6t49kXL+MXfvMP8KM//vP4F7/yuzh38QqWV9a6J9BQHMFMc9oHo7Ub9+bWFm7eXsLvfvqLWFlbxxOPP4g9837sO0/YGaFHoxEeOX0cm1ub3SaZOQ8hSAA1RULiSXVeCpbureL5l6/im77uDdi9a645z8m/ed4zrvz8qz/4LG4tLpsOGEwLj7fEHWAR7oO92eeV5jBSgTfJECIlCCDMJ6TSgNkkPyUH4cUIvCIZfJVJFH39OIHlqVVZ3bJsDLeBYUY2gYW53sTQ0D9utaty8nqzIYSoYApHLKAP6qmjB/G93/aN+Ps//O/jyMF9ALq5wVdeeAkf+b1P47/+iV/EL/32p3D91iKFKphCu76IuD1qV+tayIavdADYKgV/+qXnMDs7wdvf+BjGo1ETpbP+AOCxsyfx2aeexwsvX4sRwRyfQ25d7zPU8M8tFNy6s4y9e3bhra99uDf5z6thmZdSCg4fWMDl67fxqSefqRYe01MIz3dSCFPNkJGXSoMNO+g6yWDpr9ldxAZzCrbwBB5qL8bnfcoQIoS/EsVRnNE9e5p1KpJWikrfeBGI1FSJFaS8SRVXqJwhKAumX7v+X/vQA/hbf+3b8B9/9/sNpV++dgu/8rt/gh//hd/Az/76x3Hp+q3EDynUcj6JitTbKme9L2mkCgq+8Mx5vPHRB/HomROmpyGnUAPdNTeD3bvm8PHPfBkrK2vQKG1zMhFyClqWzqNTBCtr67i3soY3v+YhHD+8f9t+W1GrlIIHjh/G//HRT2B1dc3pk65rQk56IzbC6xXdjmpHrnMbyr4MsT+OGrwiFfkyPrRqKLw/GcazZ574MdeXe6kwKbZBNpYwyJyTspB6mweRBiN0EB0kC8cPAZlDVdqj8Qhve/2j+JH/4Dvxgfe8FXt378LG5ib+4HNfwT/+uV/Hz/767+NLz13A5qZuiFlCGs9MBcCIkSPPw+y5c/1eeVtb38DVW3fw/nd8DfbM72ou6ea5xWg0wt7du/Dsi5fwlRdeMn1pNOhFiGTk2bZuLS7jxJH9ePNrHsIM7WSHyD4QtUQEC7vn8fmnX8BTz79kwBdiAUf9CgQRkf2TT0KDnTibCMtA/YVnJMQNuAjZn84j2LeYzn3KMJ4788SPcZixNWFowqMUnFQ3Ln4swxzIBhru0RVRCw8Gh8LAGFmc5SN+3x0oDuZ4PMa73vQa/L2/+SG884lXY37XHNbWN/Dj//tv4B/99K/ij77w51hc7p4BiMck9DPvk+jg+X3jMa83G4YQPQB3l1fwyOkTeP0jZzB0ZYPcM78LtxaX8AefewrrG5vdWFg/bkThbA/xyyt2axsbEABve90jOHpwXz9SN/jgaDESwWQyxq987NM2HgE0tNBSOG0v4CgQeXV9mS63kUEIBHryAnGCrPXIwGHzWhqnHWQYuYeQIWpHpf4oXSN7UxocnS2lqgauxiHKCssQwlgEiELG5AqSVEvZdF5FBO/92tfjn/7of4i3vu5hzEzGOHfxCv76f/MT+B/+5a/i2QuX62QZxm9mIEwCTcleVmwUOTfWsoRKVV83F5fw23/8JDY2Nl1PZHit/H1mMsYTjz+I17zqFIoNRN+QQ5rGMoiOV1f2J196Fl+sm3YAkFe7hvjQ8jc+9iBe//Dp2Fd1SN8DIH0ofYoC5iQ8lCzSdjIYb9Q3G5ECRTU8yXRzJLoPGbrdKeqjgDbkROz1KzaprQwURnBzktpex5Jva1gtyowOkHlfbeOfKrwvgypqdD92zc3gO979Vvzc3/9hPHjyKO6trOEjH/s0PvQj/xi/+rFPY/neGsmWFElXVE5kqUKVjkYiRUZAI1FEsLm5hecuXMFzFy83c3aWiw3zsbMn8dqHTlekSvw0ZXAdaYqlBrC0vILf/8xTuHnnblhezZty/Ju/H9q3B9/wltdAB9PtncBCUdB4SuNZ1eSpcd/gt5PB9evgU8wAsy6inkr45/5kmACIa7jEiwrjWxGFwlREb8tRMwFKR3wZTMOgp02dQxMi2hvVuF3XbynAvj3z+K73fh3+qx/8IObnZnHlxm38/G/8If6X/+u3cfHqDeN9POqOJkzG3eOak/EY4/GoLsN2uXu33NgtgWo/o9Goe/HtwFXQPSnH8uvjoVtbW9jcKhiPRrh8/TYeO3sy1At0Urp2YGEPHjlzArvn57B0T8866QA0+BHSjemumFF96ovP4Pqtuzi8f6Fp+EPzChHB3vldePOrH8LMZIL1jQ0aLR8HUSQ2oIJH99bR9/BiJq2/vQyhndlFcWMPqRrJYt1XMJOyowyTYny62ZX6r62oaDoEn0DGJyFooAw0+4jo3qoi6e6yKyWTnZ1MsGtuBrvmZrF71yzm52axZ34O73zi1fjBD34zjh3ch43NLZx76Squ3LyNb3r7GzA7M8FkPMbszAQzkzFmZ2YwOzPB7GSM2dlJfVPeDEYjsTdkTMYjTCZjzTgxmYx7b9Hja6tOnu33VsH65ga2tgo2N7ewvrGJPfNzOHPiSGiXI0SeXAPAQ6eO4uC+vVhaXonoVyNj0+BCPVfgsy9ewsUrN/DY2ZO2Q5+voZO94/HIHmd97uIVQ0YDsVb/wSR4nlj/oWHubHlnGQBa+HCD4Y5C8HR6zKz2v70Mky73klCpJGq9yAdaK2YlBFmkn03UupPxCAt75nFg7x7s2zuP/Xt3Y2FP97lvzzz27ZnH3t27sGd+zl73ODc7g12z7hgPnjyKIwcW0G1uCV7zqlN4/MPfgcl4hJnJGOPxuHmmJ//mlZ+h3duh7zu1B/pG3/qdaZ062r3QLM5X4AgYUBgIA6RXrbu+voEnnzmPb3jzazAj48DXTvoQERw5sICHTx/HcxevOGhrBlnISFPKqRhnLKUjDMb2fciAQk5F9VwGW96h/rq2eYVrJxnCu125P95BbPHrIlGgK4CMBAu7d+HowX04dmgfjh06gOOH9uHoof04dnAfjhxYwMKe+e6dprMzmJvp3ms6OzOpr3Lsvs/MjDEzHlsas90xivFohAMLezB0DR20Yzr3m1e3aA0ZfMv4duJHRHDk4D7bQ2nyjLih6WkDaEgU5ASfe/p5bGxuYnam9yrfkCJlOUUEBxb24Mzxw1o5ZiqBExobA0vSQwDNjsmYZWwvg4T9IOWZ+xX2t65cv+f5xjYymIaMUK0UcjGdfUvX7cxkjGOH9uPsySM4c/wwzhw/3IXWE0dw/PB+7J3fFXL1yXhk38fjLjffbhmwtYmVr53u57o7bYy9EuTfbud5J4dp8Z7bHNi7G7tmZ2LIFgdTJwRHYwBsX/4cQcFTz18M850hPlrLrwcW9uDsySOYjEfY2ip2HCd1FxjrltSLPwNjgsL3j1KavJMMMWPRJf8IC6kTZoj4gftVrirARFOODqkdoXfNzuDgwh686oGjeNWp43jo1FGcPXkED548ipNHDmB2ZrJjemDKafweyltNrFSWDa6F6kOhP/++n4gx9LvVT67XcpydUjFuNzc7g8lkHEMz3JACbUF6ETN8wGvRs+cvY70eWmxFhBa46L3JeITv//b34G2vfwTnLl7F8y9dxbMXLuH8pWu4dWepeyv5+gbW1jewsraONe2ndq5THmXGncF5vR8ZisntfuTpkf8IizrUj0WpMC+gtL/Wn7z3a1+PwwcWcPrYITxw7BBOHz+M08cP48yJwzi0b29zgIcMaicDZlpDAzB0DQ3ekLFu53D3K8PQvfuJYENXlqNlmDOTMcZSJ/T1nJUvcCQ+C1kD2Dbc2lbW1nDt1iIOH1gIfOwEQnodObgP7z74Onzjm11nW6Xg9t1lXLxyAy9euo4XL1/H8xev4MKV67h5ZwmLy/ewuLSCxaV7uL20jJXV9ZiGsCnehwy9NKtQWp9DS/3p8QT0ehvNl2DpE+VWmPzLv/dD3RsmtjFgWPv2IO5kfFw+ZEhDqy9D9bcb0KE5wU5OkXloyTfE63ZX5qulKy7b2NzqTr3aDDClSiHWx5vOSuT38o3bvec1WjLsFN31Govg0L69OLRvL97wyBmru7VVcGtxCZeu38Kla7fw8rWb3buqbtzGtZuLuHbrDq7dWsSVG3dwa3HJeb0PGcJNjTYmg6dDfTpULgQuWk4OMhlyhmzA2Ui3SxWyoltovNPKzv2kTPy7xfeQwfHvITocaTLPuT7T2e7aLr1kvtbWN7rddYsC6AGqcOznJVjli8cBwG0zvj4/2+k51891sq7HY8HhAws4tH+vHVsppWB1bR3Xb9/F9VuLuH57EVdvLnbOcuk6Xrx8DRcud1Hm9t17KOk9UaYCRf0QZDr5exHT6qR5Rj6EahGo+02T6riTOZT7Dxla/p7bDA3CTpEgXztFnJ2Q/H6ixJCxb5d3D0XS3H/upyX30soq1jf0xWce6v1JM4I10wenVH2ad5b8LFfms+Xo243vTo6Uo7RINy964NghnDp60O5tbG7hztIy7ty91z2huHQPL1+7iaeefwlPnbuIr7zwEs6/fA0ra+uqxdq2ZjthbtAV6n7FUHbmtl9Ijx59zCGyIQylLa9kPrFT6tNCmFZakem26AwNTL7WNzaxurqOLRSs1ZcQbxVgeWWVHs6J1+bmFpZXVu0FZXyNRLB71xzinpdgftcsxqPuZQRzsxOMR6NtUVd5L6VLOe6trvOow/JnLrMg4cuc/gwwrK6ge0IwZwCtyf0QKA6loUPtW/1wO5FuM/Tw/oWwi765tYWVtXWsrq5jZW0dtxeX8PT5S3jymRfwmS8/h89+5XncvH3X9VGq3CSrRQX2HNJHbVGZqf/UexNmcMgpwlDvEAVy9FCF6Juvu2MNW9jcLPZ9a6vQvYLNzU0srazi7vIKFpdXcHf5Hu4ur2Dp3hqWV1Zwt74BY3llFYtLK1heXcPK6hpW19a7z/UN3Ftdw8raOlZWut8ra+sum2UXldeMIr3ftLTBk7lUv0mP2s7vmsVkNMbs7BhzM91G4/zcbPcsxPwc5ma6TcfFpXv2x05aaI8ez5w4138KgkHkB4XuN7L+Rept157LWvUm4zH2zncvcgCAB44dwuseOYPveu/bAHSAdv7SVXzmy+fwmafO4bNPncOFyzewvLJqY94d8c/gwU6Zogrtm0xaqZFeGUXyvdW1dayub/jn6jpW17ult7X1DaxtbGJtfR13l1dwa3EZt+8u487dZQuPd5bv4e6SGz1/bm2RAMq45s4BHXv6jsbYMW88c4g1JwbiI4hu4XD06crtfUC1mr331vLY6E0FWr/g3spaJ8Ny7MYndeg7F8d/Bh8ba9YNqQwsn+DQ/r1h7IZSvu0i8P2mta1rp1Rzp371+8xkjEdOn8DDDxzHd3/zOwAAl67dwpPPvIAvPHMeXzp3ERcuX8eNO3dx4/Zd3LyzhI3NzToOPMaw77bJzCkTMwDA0Hfp3gru3lvB0vIqFu+tVKRexfK9FdxZ6nK/29XIby8u1+W2zqiXlleweG8Fm5tbPmBsc8aYl9mkyX5zxAG6P3hIdbINBroRxYUJ50STjVnrJf+wolq31MHqoXX4Y45RyDDuLd4tndWIFKMTy6CH7F1ZtW9dfyE8OFLTEga2oblgjvhL91bx9PmXsbK6hoXd81jYM4+F3buwZ/cuzG2zHzVEL/c31G4oTcsynDhyACeOHMD73/EENje3cPXWHTz74mU88+LLePr5l3H+Ujdpv3DlBq7fWrTXiZpy1OhKweSzT53D9epJN+/cxc3FJdxedBS/W52gS1/umUOsrK13qwFZmIH0w+zNxq4OaEn12AgEvmFDuZ6kNi1lRi0C8SQtaqiMWB6QGoD9DTuzs2TN4s3cv1iQyhchUFz37vjKewymAlCfLRlQ+uCgOk3R7uihfT3D3W7Sz2WXrt/C//x/fhRfevYCFupZM3WKfXt248C+PTi4sAeH9u/FwYU9OLCwBwf3dZ+75+fCqeGhifzQ2LXmotvJMB6PcOLwARw/tB/vetOrsbm5hSs3buPFuor1wstX8ecvXsKXn7uIZy9c7pZ+TX+CyQ//d//C/tLNvfqp+TYPtCNkh0T6+J7eMsbyoLKP5IHrlZkaYsoAOOrGao6CLW2qEYUUq58aSeYF0ab8KIsbrw0OSq0X4d6QjOmaw0lMA82xHFQiiwMymLMR6706wMzMGPvTXzxqrSYNIfTS8gqev3gVTz79gvdUnXMyHmHXXHcKeb6eRub/9y/sxqmjB3HqyEGcOHIAJ+3zQO8PUjJvOaLcT5rXkmE8HlkE+bo3PIq19Q3cvHMXV27cweUbt/HM+ZdtLvLshcuYPPn0+QoqES+FJhqsbQ/UA2icr6YhDhhwrd+etLJzUH1Btt50T9Rja5nE+4AjLzt+M5WRHhk6t+nshkFRRJfEm2rX+ZZ+h7FtUwaNSBkwvO6pIwftDeHefXsPpHUtr3ZAaWouzuL6xiY2Nldwd2nF+SHHH4lgRg9wTsbd90l3LP/owX148NRRnD1+GKdPHMHZekLiwZNH7WhQyzH+IjJo+cxkjOOHD+DYof14A87gG978GnzP+9+BpXuruHTtFiaWtRRf1iuaUpQSUmyzaRo3ixfxjQAAIABJREFU71+Nygv9XU3dZy9MQvrGT8yHteLmKwp3+E5lsW8dWDVSlbm7achPRmVSGkk3ZJ/z9j02/LkAVh3pUtMj1UXvD8WYWFkGvYEAGGYcteDxV53CZNx/tqO1qtjSv6bJlhGwzhKPqGOKKsNWKd0S6upaL+159sJl/NEXnrG6CgqTyRhnTxzBI6eP49EzJ/Dw6eN49MxxPHjyKHbNzWCmOpR+smxDMgztr8zNTDA3sxeH9y/gzPHDvA/hw6UpgaOYvu5ePCcWGuyA0LTioYxIiio0mPkYeXA2TT9UYSW+/a0fDkwYqstpkW9u6byaJ54aJ01hltZ4WtRLZdBfXRKbF7B+SvdG9KpPm2/xokFI/2pqWus3ZTD+NToUVyPx/+jZE/aOqE6N2+8xuRq7OjcXl2xjzzfElUYfkX2cq/6IH6kIIDRG2NLHhQXAFja3NvH0Cy/hmfMvB3DTP3559sSR7v962vqBY4ewsHsX9u7unqNZ2L3L5i7ZCXu8JmeZqFYLGaYasw1HUlJPeRzdG5Mlcy6ztr4K2dFyHX43kRmxstukh16EsJSHw1pehrNopmmImGN2/HF/Ka3hUFHUiI35Ss9cpt9ceTbStX6cwPVkCBFWn39nLy8Fr37wFMbj+Cqa7XLzXH7j9l3cvrvkPChYBVBh4ycZlB8FsBBd718GQLC+sYnnLlzBuQuXHagAzM7O4NSRg3jgeHc49czxwzh19CCOHNiHowcXcGj/Ag7v34uD+/ZgZuILq61oUh8hFe8X1WvTpI/MJCC8DyAqAlBZVjIQF0oyUhWvFCavEIQcnD8ZsVqeoQZV+cvOwOgfUyyE9NBQO0dEUq5oH50lxzQP6PUddAJSNB3ayc+79+ZiQn1TlFaNz++aw+MPntw2rWhdOi4ra+u4dvMOVtc2+ilzYMdcnXQKFNPBMA7tJEPIOtCvs7a+gedfvornX75qdMajMQ7u24Pjhw/4w2oH9+P4kf04deQQTh/vjpEcP3QAc7MTk3li3kwdSOjUPwoLY4ZIvGsYNAOXlB5FZfqKSuxLHdTuFQRn6oFrdlCl0vqbTyxrcEgtQ7U976WHotUwLZ6K85nCSCMKKaBWtA7zGO3H+Q7LvT0ZAjsIY1kN6aEHjuHYwf1RL9I/umGt0qT17vIKrty8XfvhQdcP5c15YmDK0QJZl1GlTRkskS1qh93SewAp00X3ZWNzE9dudidrVW+j0Qi75+ewf+9uHFjYg/17d+PIgQWcPXkEj545gUdPH69HN2wuQGGPeLI0kW+kCvZ8h6ZalvoV30vQ6lVAdbyewRUKoyyvAi2ykXaV2oZbP4lWnuOE+QKK/ZGOkMax7HWAt412zAN8sAvUAIs7otJj5wwRYhsZQiqm95yH1z18Gvv2ztvYMK/6PadSnFLdubuMl6/dAlmJzeNEFBTY6RNiAvwn/XrgYExvI4MEA9CU3pSCuACCIGv9AaBgq2xhcanbU7tw5UaVoXs4TpeM4zPV2RmQjc64rUZCp1YDotZ0B2nFhgzaBpel0ElWcoYeyjIyVT7CODDZzL6RJDQ2unEeI6Ts3nPMmuYY+qV7WqQ71tQHavRsmga16e3FJBkUrNwx1WDqmIjgTa9+VXjeRctb3/U3G+O124v1XJXza9mgHaWmsbRI4M7cS69NgJ1lcAQA+I9RMr2wqNGjp/XiONgq9VaXFq6sreNmWcKIw154k0bgGjUXFEsVAvRph6XUkJiE5xDISjOBnI4oP6VUbWkOqf3U8nqv1N/FQlm9Vw0qDgClAyA0Np7Y+Ao8/LszGB/VEGIGlp2mgP4IQmBD38xnLBYVraYIhbQ/IEP3J6cQh8LsouDE4f143cOneyd0+eLUKciH7tU6V2/ewYXL16uhueydVorx7gAAu6O+oiXGG/3NkZ1kIHRKWy26vFtl6NVzeyk6DvchQ91VVxOnQWclATaw+pC4MmNOot8buaLPEYQEd8P1e0KoLoGegTD3UcO8fap35TlLQq+Od17ZoI+MdMYLyUQ278unhFSEdIaeJqeSc7nMF2s7IT2UbWSIcyR40K2g8vpHzuDsiSPB6PkzO0JO91bX1vDn5y9heWUt8FwbOI6Tgau+LA1Vsya9iYKnYEcZHAi7fhyvGHw8TbdxKWruyrfclwyjbgGDI4GPmr2WEoCuiXsa43Qtn/bKwTGYuKK2GnKeKJozEt8qtAeGiLqwNmmtWX8T6quCmNXCfLJsJX3PUQIl0kcXS7r77DgUzYo6COuF+lGnKj6UQzJwxDBIq2M/Ho3w+kfO4IFjB3tzB54zdF1K7zcA3L23iiefOe86rvKajYS3DSONmY5H3jOpsguB6oAMzIuNS0nlqjLWN4GqgeJ9yjBSm+zstASCYvHHOQlKC06hCqgEegPcFzbMNANbEo3EtFWIL1eQKrK1ps65KAGYGwlo0w1sfL3OrUOPqr5ZFmTIjlkVapNpLSM8UHWYM9HNIRmCxsRrlFJw7NB+vPGxs9i9a8544bEbWnplvheX7+GzT51ToaCbs6IvJO4hI+tL+wqwHe8FC+7LwEBFOG1dsBshfDd0DWB/PzKMNH2IhsaRwRGkQ6fIhpNyoQhM/R55LTNoTQWInVJZL73Sf4oZd3/+k5XkCMhRSRIPbiDMs94X+BvJGaEdnXQ+FBYjWBbhMSKAqOXRzolGSwYCKuekq/PomeN486tfZfc4Slj9bdKnrVJw7sIVPP/yVWjEEusXidHsFGbZSYZk0UpvQAZWgdC/+pXLSt/oEhjfnwwj3fSye+YAyl004LhrG3M65UztpKdwZYQHgCa+xYRoISz7ixpDXU9H6Rl7aJ+912RTfTkDOvkrlrbQmJXSTcqonoV+7iOMuVhbcyiWQ+tlmxr6TTJYpAECIMzNTPDE4w/ikdPHuxoS9x2Gdqf52trcwv/zx1+sf0qg81Y7cSDxyEaMcmzcpV0HBXa0fkAGjRLBFgqXw8a+k5H74zZSJ9L3J8Oo71geHYrob2ebJzMhVqTQUNKIsjN2dkSQKkQ3h/JqcGZnGkprOxFaopN68KJQtAiwS3k8Iz9ttNhGm8lEBwy1L6nRlK0z0dNVJCsLwOK89TKkHDW3kcEnri5DQcGBfXvwxOOvsjebuyo8wuT9hlxvZX0dv/XJz9NUJxp3S5zed5FoBZwCivPQkkGjhPPmNhjmPgE8HRQ1awDwimRovA9ald8NqJhnwTw2CFzHXcObejCnWb77KrVuRHNLXSoRS8tq9GDlQLIh8P/Urw52I5e39EXbG7k+X4Y2lfcQDXj+o11pWsS5USGabCKFNuGgEV5hhhxqQAaPqDwsgl2zMzha/9jk0NWaO7CTfOXcS/jzF18OVuOGmHRkTgYDJaXpsrFTe9mQDA2O3cisM71D9etYFbWzBEY7yWB/MIUn1DpGPJnjXNcGw8KPh0pbPXIOXEadsErrnt9XRDD5ya5cERLpsQ6rI/TSAmOthL6lkHzGlxhdtmveuOtM1vkUU35yRFdjdCKw/ORo2k/LMEiGgMYqcyXFfzUor8pxCtU8RiGCj/zen0Q/DIMARCOOiY+rUdwUeqkI7VU0ZGhdeQUxsGagLL3br0SGkZWXdAISDrxxvZfpO1KHkEsiY6B+MAAzbPZ0CQ5QkhCc92uY8s0Zdkrqk1Mc66c4X3n+QXOVbqC8vKA6EvHgrGj/VYNFzSTqI8ggAgjJEAx5exks1aqGvryyiguXrweDbx3VyJc6yp2le/joJ58kXfAYlF676Nhtc+63kmBNWYZ+OzpuYv+ShTVwKGQa9ynDKDqdo5c1LLRuS/870LJxpb7UUFoCcghlCNbONVJomiWRv4jilIsTHVeEuG2bWG5YXa3YOGaHHj2JYp0fOw+O6dkRAAnL0nVWZOlF1bOlQsXlM3p9GfhytQhuLS7js1953l883EgZWt9VJ3/4uadw8coNQ3WXAT5WKkO+xO+GYjLY3j5SQwaOOmHH2r51+jENWpVC9eQVy2DPf/v5cw11aoidUYqktImEN2nqvSAYTeRcWFQDSKMr8HydL4l1TAP0PcwrOBJWxzOHIhkrzHtwqgJ6qKdIo/dMhg7hnFXqm+ZMHRkfUO1HFxCcx1q3+KKFB7m2DNpvTs83NjfxR194Bn/wuafQsj1OmfLkenF5BT/9qx/r/mqr+jrLZ18jwvPVO8JiHaso+V5fBgYDyVEnoHzUFTuT9fkKZBgZmqoxJvTUfwutAESiXtUnwVSFo0PKAdWDC71tTm1fJ6i8fEaEGtGifrYmxMEoCGaF6CbZObQ627QCp/WtTuQvKj/zpewK0VKemE7sqykDUopRZXjq3EX81Ec+hqfPv2TzCb56x2oALC7dwz/7xd/CJ598uvtbEAQ6wbEkF3AGEE/SBq4TYDGWt2Swytl/xP4Z6EPi71cgw3ju7BM/1t2n80AV+UQiU+YenNL0+CRm4IOsyBqX2pQiRQXhk6USaRppUlKOEgES4pKpt1UZ6F79HlbG7N1KXl+q4/vEnzYFqV4XfMT4cLlMUTZgvCKl49T5Ox+xaMhg6gjZOHT179zFy7h+6y5OHD6AE4cPhEcqQeOxtVXw4uXr+Jlf+zh+6iO/i6s3F+l+jEw2NpR26DKzL4EXlMaL29xRLOjtKEOI9hGnK510ZF0i5r9SGcazZ77mx/pr1dy3H+y29WEVrpTGA/GBnY6eEfBjEkrRjJEQ0pboLO/mdiQQnEzPadjgA8oQErvlwVMdgwSiVT+qLIEXNQIy1vhXacjZrJ4DgsoaJsCge8RRTwaI69SONzt4bdVI8eVzF7C4dA+j0cj+Xp+I4O69FTx74TI++qnP43/95d/BL370E7h6azH0SaLqiBILOn7phLMIgVwETVUJO8p2MnTqKaCz5M6bDjnpN/wRxb+ADLLwrg97QsBGWb0cTKzhgUrYdwzj3TAlKOyd3ie5I8AGC/+Zy7O9Oy1xmNX6itq9VAvu1MWNLm8Y2Z+BSnriyNHRQd0EUjrMIzOK/n0g9k31WGCWwV72RlWHVpD2zM/h8bMncfLoQezdvQsjEaysruPyjdt49sIlXLlxp9emf20jA3xsG2xvQ/H+ZeiXF4sSodP/DzLI3nd+uKiXSB1U1DdGlAB12hrJ4xInNPi8fNsa5DD5MsPYRjI2Hq5nhtTx7nU9tjUjQsdE/MlDqjQkaa034jB0i/WobYg4mR929pL6ENdLkkEdQuc7OSVxMoXK+3W0Jt/PV8xWdrK+lNtoi+2caEpkGFlupWlHcYOgPUc73h2ioKKh/rQJTFemO5F9VIbdDzwJyFWJtADdiweKl1taBfhEzstMHvZeyzOJX7oHDcPMl0j8ZJGL0mT5WVYSoNemhE/7rsZRx8L7a8hQYH7CV4g6SrPq24/hlNAmIC031fo5khePlP25qZ9gsPZ+M2DAtMkw8omvHpKDDXLRmrpJVo2Ppedfzc0ejgAmfcmVTPpS0spwANtOk72d10Y603O0nObAfMD5FpWpVLm9n6T6rp7ZqCSbTyPCY2RdOWgoRZ9DSKg7JIMBSolyMbfS6y8QNB5baYeBQ3b02rxPsy9fhPmke2DqZBjxLrReBsRkKLb2zl6llWu4S1YDMy77qZBejUDblu6en4Hi5Vak3JEmm9oWzpMhSCmk26wMktl4pwHIiK4R0groJvGpfYRJWzXkjAHB2EkOu6cyWJ0hGTTi1YhjAKfNIkgVe0CJ+2s4oMneL7dzVsKVUkMCwG54lS9ptJkeGUZsEJwkOappaNF2FHREU4xangcZtggXmcroUBt4OJS+MwbQJXr9oARdzXHspTZkfeG4MDHnswodPKGoRo4Z2vltllezMgMP/nSJ4Gd6lQ5HnWEZQscqe/Rm78VSXpalYZyBZAk+b+lLzzG5OUeHsIAe09Te9dWXYeRnxfkWD5yGiwpQtLKRiTVkIwGDVPETMA/vpV0kt+bO2UEs3DZ5qM5BYbYAPqGvCgtTBNa19dWgX2K7JArUyTsHJxoc4fS3tHZ+yaMaMiRm0DcMbePR0wWjZrnPHg2B60iavbeb+zh7BNeigcjyVZZhZA+sFH3YBoij7J5qUSI7bzBOQuA8H9D7QgNdKqImA++jKDlWsX+cRc35M09UZkvDAHTDplRjj7vBjGaxr4D0pCc+qOe1SVEqbuCTz4glkChVfyZbX4augA2E+eFrCJGBlkeHVJNoOLj7KYPW5e3FPvI5OeHUaIpkGHnK45MSe7WistUwlmFeXSjJqFeYeYpKkuvAkbkVEUH3+Xcjj7TDd+A0TPpNaorCq1D+qXGTdqR77Hjfvoxod8mQpXv3VJXR9J9407+/YWnZgAz9yUk9n9TjcOjqt2+BMHcZVvu4ZYoCnnXwuDjie/n0yDDqA3E9xcnHFhCF5By+F/okO2U/n4uM0m8yRvfkUgMJG6pGssw59VfpSeXRAbh4XU4srZl7oL7KxCrxKww5eBAa5eClSO+beCpWmjAnvgy9tpEhCE6A1Vt14+jDbVmJQY4h2soPDRIvRgyUc8rUzJSmSIZRH+z0aAZ15GEkZkvFQ2F4loIdJYeuxHDmW5m3rEpXn8jTSpH4FpcqVLcCRsqx5ckqAuX84Z2p6njGAB/LVnqUd3LkEpATikVXIceMO9qdcxdqVitFvgzBhmXwts5PSaPfpSY0jmGyxGQUcDxy+x9q6WTyY+muBj8bSYsCzqzrhXL4/sR6emQYmYOQcbgxeJ+F7nX0S2SG0qSAZBziszNoWLRQSwZKUOu5XnRKdx4xJdxXmK20+6dMnV+jwxGnR7w4+oQFCHJKks9JSjLqjo+SdToIpwj6ccJVV4F4HqcGzYygzcsxW6uKeGkvPa5tnKw7gW7YlimUYWQHs2gC2f0U9+aS7EGSddSfnkrRKc2wkqRtiyPngMfb7jN5dukZJykqfzJaqYeR43j+LlE7pCyWU11TyztkUf4k6YT4VDpCO8wZxer9cO4/TnDaMqSXSLcdKJup81hCUTYV7TLS7J89S22SVca6hh4QpKM2UyLDyCaAhGoWtdWrq12bQwf6bipuk25kVp3bNKJFXCHKB9zo1CyovvZTFRnStJQLFnpE1pd2OsH07SIWqUhxhctKFD7jYWG+VGm1rPmcQP5kUGmBYJaBnN9eJbrttSOEwgBAuwkAwydw+238+1A/UlNaspYpk2Hkh+L8hqgRBEsmYyCn6qVHhraApjO9E7mZDzVgRszIpwkTbrBuOWRzNeMnnpnnpT6xRhLaSFVeId2oE0qgDQpWZPQilrPynxf2JUcKa9SnpU4ZNLIM9V7J/ISmTMRXu3rPtKkzcmBlfhpPrTUW1Y1YbyndWGg4/BTJMPLB6AtnL/yundFH/eFOwKsoXWrug2pr6dxLBhKOFDm8VAYcgVUa1l5sZ4oxhvt89jqngGPyAQYYPhBRJ+Gqssq2ilM3pHmDReS4gBDbJhn0HqWhyp8al+MJuWvpq98E1ZdahzRDAv+2QdpUAFwGSXQk6WMKZRjp5JiXVwv8vKt2K/U/fdS01MGueKhD2+vb1u7tVjXk4J1uhsW15cZS21jgaOSEdLPjtyrY5kDk9IUjmTmR9+yrSTFSeSxhmYLXeuWKhj6YfVm7moYgDQOjgW3JoHpJ9UX7MwNk+FWLK15U25q5FWpnLQaiQSvnb1atvAY1TZ8Mo0Lhmu+pA9dxJaE0lVD6tOWkS4QmLLsMG664ExYVg+rzfEJpVdpstqGNKcLr2nKfVa/OXVxn1jfDjdCufTEx3cs5pbPoxQ5Z6VOaVFjvjBxAGqZ+2aAMpIP4PfEY6jAd5bPEtnQ7PNuMHZ43UBwhWqEmp8VgutMjg0WIGF7IK9A9UdYZCB/m00+NHYnxEn92/JPVUUrTY01XXRKtojQkF6KBVKLg4yRKHqwSx8eBpy4jFopwDf3QIMRxrjOErCceRIoUEgioCsQdcxsZ+srrX1E1HImpr9C5ddQzSl15LLbMLNZHWrk2WmysDgzTKcNI/+Qup0w6kewMxjfqWnwra4yiKm+Qga2D6hjzbNQhIhWrFx80UufSB4eIweI0CURq18X7yqgf9eMRxin0v/NtUn4+PCbWJ0dJoZsS6Vk72UaGoCzXRY7oTJPz8HzFAauglG7yCqAxMXRUolMwPxseMMHITo8MI5vsMnBXBpSvYuV0GK3S7wZJHOXcfvu6oY6CcZtxZqOQpAmmp07AkYQjG9NmRxOqJ+keOUtuG8INaZ1lCJEqy0eOkHQReSR+cvssQy+0UIqoPGT1bYfG2yI1Oy+SQQ01vI/Op0yGkWJZv/9quGZjxFhGf/7FyMWD3HuegNux0NnbqNRWsTrjCs8dIJXB67mjMZ/Jbf11GgiC6rJrP1eMUSkpe7i/ThqnqW29fS8dHpLBFNO/WnPdXv/tW7X9tgR27OM+mnsfUyTDyHKtXkbgnuqhWqB/UcgdO4U3wF5UYHMPEQtzQ0YeURscluBHLPiVNAiRgXcTzJmFf+lddRzqmxkr4C2K+qFPfUGzgEQXJkNRGYJeOCrRfaNSXJdofbZl4J+hot7OixP5fhaiAPpXfuIDPdSwRSxfZaDcbqd7UyTDyGy6xNwtrrnX/9TwhDNkQi/O7UTHPjtCsf6sNqFlYcfQlIjyQDu3xDKaE6V0g/rxA2POo5FgpUt9eo11ojYYDLfYBqbzofG2epVFLD7Z2v3T26dQApbfOgAMyWBOJ6y3TgZzzPqdj9X4+LWBkN+20t9ENCEgZAeFv4S5l/atPbolCwPHlMgwKsoYI3fp0LeYkVUjpLxfghYQDCdczC8bgCElQruwEgX+SuWFfppOVdHqSPpViAePKODfgEU+fe5bakTU5xFC+0pc9zNURYVDS0CvtMMQutd1LBu9yqIbzaAMKndWeon9BTMIE1KKioUYsy7UuTMltgPlk7CWh88c3HvMupgmGUZ+uyJxPezn3ldXmUKaZDxUBdCsXbysJwl5Ru+YRagXVKYe2peJwkQ8KdtwVCYn+koT7Y6MMfNrRdnT4Ue9A9s+QMZXdv4knySerYwHtSGDB2d3mn5dQmNKN4kSySD1e0VPbpuNtuHh0rvHqzmpPYHCNMlgDwj5J0UGSlWK9B6D91QmpFDJc5MCwmSyxHuxjMOnCuk04+50oseRzOYR3taOzRty1MhgPBYbmJzvhoUndQApoW04tsL8soxGW0zXxlKhz21kMI9VGYTq9v3X9BjvV4sUP30A8Pur3LRMa73VNuILfKuPLv5cQyyfFhlGvPrJ3sfnZYxudtzgbKkD4QpKx+nzA0XZd1TwwDS/GS/xF5mk7/l+YtvzTD3OrTx2zm/pSuWHWGPBPatUvjj9IX55/AokGjojo0YmH/tBGQIjVq30avicqCGDkabTvazf1C/z3Z8gS39MVTai1V4B+urLMLIxyGHdEnTUQXdDgTLFzpRzn9IoS6L3lki9IUkJNxJNnZJGQtwytovfKxF19DxVNGydJHuIVbRnRYfgxtHABYFOyp2Os6X0uG+xl8RRbLUIUoZlYGUG3fWPOEt2cKptB90kPeSTwJEswnTROgLhiyA+pp7uiP0OIz0lMtgjpIbY8AeEzNtoMHSVKfiOcafeGG/oIb2wgSYShGsHCY0KVb3CivKcQkTSyV49d099atBUxw/KLvXV9d0cysqMx65zRhxhGXJqkMjXaG68ijk1Db7mWNRID1cOykBlgDuu/1Fyr6JL4FRUAaAkGUrQLe/1BJtlYGrEq3gpcjIM9g/0TYMM9gipnbMvjq0a/jWtKghtA7Phh9lrCfeLMaJIR+FTktIs0hUimw2PQhQz6CxQqKTwSeVhqY8iRH5bnK5tW58JvdzAC2zDwuErKqm4bv25AR0hqPK6n7r61ZIh9A2jSSHVVNOEHU7vlI7Ee3xwktmIz4oM6QI12+WTywJ7g+MUymCvoTE1K2IHhE+MS/qtdRJzIapYLTfEsJipEhsaI7ZNAJqYolyfBKayMHD0vSPbNzSxZdgqYxhEOsKiiOad+sA7tQbfJTp5SAPEfIrl78tQNSTOQRSD9F5S1NK6xI85KYFBCfe3RUIirpNnH/+Ox5gu8inUaZFhxMQ19+sMVKB5NvtrHo+wmx0koe9sq5xLsiezzWRbEnVEQkvVhgDIzmAhqdTB6fkq7Ub7SlmIOGTc4diKtlH0Vk9uIYiSUx4LfWeaNrJebH1W5lsyeF+esxu4qPxA1HUoZ3oMZE48qCQgZ+038xNcodIiHmMqGQFqGmTo/iwvR3Nul4zfUL0o02R42og0YdEfjUuRlzqwsJmUYZs7ahw0qdZjHbbbXNMeT8NKz4Yg8F3mzJykMnW60hdEeOhLqm8RINNpKUM7zn3D+m7JED5hovedJl09FhppGBPnf6O1Zrqe2DR5HWJsimQILyrrP93mZHSeoTN1oxzy/xIZY2NiSRh586AnZ9Bowmv25oyDSkhtmB/ro708GAT2H1BnD8c8ihoB/F4ICyURtUbkyH1c8T5y2yjD4HPLqPdS1OKoblPbUs+ahXrOEO/0lsRPUVswFbgd9PdvSuRtSmWoq0zFBTLmnctufGvn1ZBtkqROot89QfQ5hKU0HkGMSY6tnJ9ZyiJ2G7kPXaWy1aoS2+g/hfowRdO8g/0k1XVeSKYc9gt9N5kI6tgvRcm5XJZB1XZCegi+lWTwP+rooqsMAoqkBeDHWXn+pqPJRqlvLCygKEg8VyKw6Sq/OKDqy1fk9GEp51X0r7IKpk6GLkLwhM5GoO5MGxp6CtQL/SL2F4aCZOAyuLcWmCFH1CZn7IVMMcDtbepYm7RRJCkKFFcQs1qYT5atpO8MGLWwt8gAikzipS67OgjrhfpRpyo+lEMycEg1SDNAYSCKffC6u7DDa101ahfZjbvQbnA+0h/GTMdDghq6evVeAI/pkGGkNlk4nDCK2US2BEYYGYOQ2lFvgPvCxnSL2ZJoJKatQny5glSRfpCM6Tn8EIBZvW5DzGu68fU6tw49qtI0ejibAAAPLklEQVT+QfDDvIMrMNQ0LXcy5AzT0zy/OSRD0Jh4DU8DyNCC3qMJ9mWEj40LBd1dF15MCDSYlvIVYDveCxY8HTKMNH2IhsaRAfATl36aKXUdhCIw9XvktcygNRUXXg3fynrplf5TzLjz/KevJNrhpKgkiQd3KOZZ7wt8+ZUR2tFJKs/hUBvLIjxGBBC1PNo50WjJQEDlnOhmoTcXMC1mV0gdSXsByLq+xPpFYjQ7hVl2kiFZtHU+PTJ0f1IrhTXfnVWi3oHmdYqvDvYuoNoJb7xZKlQAn+gQc6a/Tml9hGV/UWPQlx+UnrH3DtPxp8mm+nIGdJKnR1SMpPItJdSz0M99hDEXa2sOxXJovWxTQ79JBos0QAAERdigx8LlML0BCmJO2NsI/A/q0MqdDK3zR73HozmI5Xr6YMpkGPUdi3aJRX872zyZCbEihYZwvoi7ELUjglQhutoX3Vex1bsLtQtb9lIP6RWKFgF2KY9n5KfX3GuUFJOJHtjRvgSIRy369ApbuUaXrAxNMStwhvmcxHotGeLhNTYqOhIjzqeQXlVvvDmGql9ewYl/W8+qNMXpfZd0XolTQB3zKZNhxALYLYV4MxBJ+S0JXMddw5t6MKdZth1fnUaIceXTVyHicprWZweJSuT/qV9Fg0YuXz3b2xu5Pl+GNpX3EA14/qNdaVqk8hqPGeKVXy8S4is41IAMBgzEei9t0DKhe0Qvr7roWFv6HCavaohJRzofs4ip5ArJJj3WzGGmSIaRFuQDUCV0VEKua4Nh4cdDpa0eOQcuo05YpXXP79uJSL1HduWKkEiPdVgdoXcS01groW8pJJ/xJUaX7Zp3rTuTdT7FlJ8c0dUYnQgsPzma9tMyDJIhoLHK3G9RVcLEEzQaoEnvdk8IBgMrjomPq5F2gXupSAkp0rTIMLJyerO0phyKUXG9l+k7UodlMBIZA/WDAZhhs6dLcICShOC8X8OUP3zCTkl9copj/RTnK88/aK7SDZSXF8CfIixe1rGi/VcNFjWTqI8ggwi6Z4cdAUMqsI0MlmqJIObw/s1X1Yzh6JfJh0OUtu+Rql/s2G1z7reSYE3TIkPYqealVGtYaN2W/negZeNKfamhtATkEMoQrJ1rpNA0SyJ/EcUpFyc6rghhe69iuWF1tWLjmB169CSKdX7sPDimZ0cAJCxL11mRpRdVz5YKFZfP6PVl4MvV4o4nUKPIYNXRlp6sheqproVk0H9IhnyJ3w3FZLC9faQpkmHiUaNSFI8DOhcofL8hvEkj8WvrWQdeDSrWl/fd2ktwQcmJeFakfFIKZ80CD37Dj434RBqsNK8I88gWzeA0kY7/dOVIvS8gWYkey+9Bri2D9tvTFzlS2Ak2Nm2EQj9uiMR/CQ3pa8oWuIvWGCo9oBFFpkeGkaFpNcaMnvpvoRWAwBjx75NgqsLRIeWAapT6MJL1qEjI0SX8pRk67Be14RCqyJBy8xBXhegm2Tm0FlKoZ1MaAbRO5C90+v82dyYLEtsgEBX9//9MDlYVDyRPcov70tO2xCYo0GJPTrkkbgFPyUQ6nddVhzVKjDl+Vz8DX1LtaXFxh/yY17cL4M/S5kp/NZ/8mg6/CqQ4oqs9tQTU9PrvDcjbeLog2PTmc9KmWB2Dm2xvKHS5mtWnvrBkyr4MHAsR1V6TbLwKRjk5WhZ70CvH/MKlEJEpuBTbQYIrUhynWmN/0cE/O3xq9a9xmjGafTycXcnFJR6Ct9lrE8b8Uxlf9JvbO1Csxed0+M0I08pA8S53laOGFM9rFUlqDz37XkLebaxY5aAyqsoe193JvLfa0qcM1VYMbC3dHI2zeF4yjZ0Z9uL1MfdvDt3DewSb20nf0pXjoINqbbf7poNsCnvwhHKAVr1qRDaWaCVbHEa9gTPgXWis/1PozEVaJ3gF5PiaDj/WbtpRTgsRQKutb5cEJc4ZHEa7ll1Wja+cnenx+K3gW4sBk2ZQ9I/SwsyBICtWHbDbQS1BBwhLltyBqQzolB6xn61eGxwe5fSKmKTh+dm8iXyct3ke5AZ3HTj5rmdXJvyGZe43Rjk603vLtBScTfj4Ze0p0Ede5s8m/DUdfhpc+9UlO5tQTx24rswitK3BCwptNF24v3EghiIHn2j853HfZPZhxshG4f4D5ZNLTtCIPhqrbRQWw0IefxXdPpHM835DvQ0Kl//HduLt8nzr6R/NCfdIuNSrPtzslO6v3qtQr1+FiZBN9pr6NLe4BslXdPjFduZCTKWdaAOm493K+CVpzzCMUq9QtbKkDHPsXgakI59Y63kJVSKPhv+uiVxdsz5EDZdfkLdZRYftIBcn7JRT+mPwuKPd+8SlT7Zv/60susei+F10EDiMKGmlu2guOdoMxmo2TzA3J83EUIWrglVNSj9WAubnm+cU7kM6/Co96ZDc8iCnWmqTLJDOtjYtmUytVqFGwS6QD7Ixq8zE0JU9UaBv8GTr5785P8kaGGU3yuGDfUSjxvHRw/66AwiJHE3TCY9yGU0xb6ll6p5p3nQwoGTXi9LGwa8RtIwFiqv3vc21dveT5qlfSxHT9mt9ToffPJO+aW8QroERAgejSo2VD49sNTY+dHRaS7hcRtBqTTxn1dsJRykrs9DIROcFBMmEbacxoLNlxwBMRFeG9AXc5CRr82iTtu3Ix8se6ETQw/ekg9u86aCMtzOOAU7dOkil50/kdwlA635e92pZsNHoCAB8hldyxaXPd3T40SHaHN22V2pRPySdwHl+OtGqtmHm6DrRYXeodBhnMDbQBb0zKS2t5hT2og+8rx0XhnA1o9LgBbIaArP1q9vU13PgRwgpMCTecy0q2bLOuw6NsXTv0VxcXPJSl4tzNpLZYt7lyxGY7M7sIIkAgrdB+4gOvzorzlscOKWLDVDa2V0nsYtuULBp1b/XcoQfZRf0Vu08A8Tp9irDDg6k2VyrJvTbYG2KQFub14V+9n5DlaUgfwIcNOaEPxTAkxgi6qLDEGadjqE+lT1LMXSbPA8ascpGc2nzr+41zpXBdekls/zPOvy8BJnacFurj3JFqrPEDN7mnEDgOR/Q/cBA50bU4eC3pYhWikwUUM0/ZcI1b3St5ZWM3M7el2yJZp1XQ3rYiQf1qjUMJXWbnDwjNkAit/2s26nDc4EOQnn4eUPktW4R3UpN0Chwr1MGt0/1D3/Nc3J8XuFLOvjNfUazFELCGS7O8i5rKRUT9ZLCIyvFbLMKmW8ZceE+f1/qSB++WyzD4uyySxSuQtW38qaOep82aCVeS8fPxXLk8P92MOpLX/LabwVxWfaiwzk52c+jHBK+fc7+NxAmy7bax54jC1TVwXEpxK/r39HhdwLxPsW5NzrOg2ZATv69eJ+/z3quC4rfcMaK5NyJhI6qTDYlB79NL7aMBcBZbVlYultFoF5l4kZ4sq5lIqDRTF5Ceq+gyLfnhHnIxc3INx2a4gCsY9WN2Yd9acSmxxttyYNB4mLEy3WWTNdK6UM6/E6wCwAW0WgHBvllpUKeJ9EANsGO33e5JbyrKp8VqkjLjBZnMtizAgbjeHlyq4CaP5itFHgWgMeyRQ91JzNXLARhOLsGArOCYdtq6XmKsrmzFuSuTHnXofqWPDlG/ylNMI5tskQyApzK3N793fapXeUyQ52NxKJACVt2QQ1/Tqy/o4Pf/k3nKGconol7D/3swqBMakjGFD+DQWnRqRYOCqjlufZmAwdP2Aj/Kc1u2ucp05LXdJhxDuJZ6NMWIBCU0K9IxnDqR47jwOQrnK5mnyK8bdWIz3G60JwIev0UZqtpRF09yuPdp8hWEGjDNj+ow88HszCBfH7WyU6P8wIVSrh/VinVn6nu7eR425FfIt67z4jsPJwThprfRCtFGAKn6vfo1oGxqKdCU9cfZJF8MWwCOUUnsMM8UWzfD6639wnOXYd25Hy9BNB005Ix26XpKmLZafba/tJneGVva/RYsfqJ4q/o8PMEEKjmrK2o3n7tgG70y1XKJ8vJ3Jx9LtmirxCxxltLKbfNvbBKJUO2Mm3UgokjyrW08yimt4s4U8FwyWvZlZ94mJRLRtvXrs8JzG+Cyg0Epw4Ifr9K9M/Pv0LoMgCITQOYeYar96m/3/jELmnhLR/T4eeNDoSa3ox9rDZN5EuOaQ60XUvlDB4YO/URb6PtumYMplzfoG2ZstnM8oyn6rDUF+4UrY8O8SVsoyCMRnshWcHpo06kBuY2teSItAaeLp0maEwd9r2c8rSuJFKrXXM3ycHIxEp55lNu2fB5fNRnXM61jGojqXxFh18NxqmcnpXPzQxf+0cFAVdRntK8BtVr6eQygYSZYqaXLUAhsLSh9Xo/G8YCn3IezJFwrN9aBgw+8ESbtM/WNf40nMIQ8wZn5L6A0PsOHXQPZajkk3MVniBc8zS/FdVLrVuZEU1+b5BeDbBKhxh0Ytjjgzr8NDnm8qqe/6otdD18EX7UNPdgbzzU0B686+k33dqO3KKz3DDLWuUsu48Tx6UmxM1H3m1gz4EQ9MlM5iAqzrWa1DMVjzfXnRa11XijYQ3mqevT0ghycTAM7E0H2WW0D/GzAxJ+5XFZl3Zfu1uin3u8ZINbzX9tumVtZvqeDr9EuuY9BfAeVyilUkL0seWkJUIry5Ch40YFYUoNtOd8QrQ2bbpt62NDVFsv97n5Du4sm5k34Sawa59Ws6KcJZ2zFwNy00eZlLQ7kWOtMUzntVcdYIP+95CxtSEdyZm9L24XygpgCjznp6Y/db+1ZFm8SPc7OjhD9PSCqFjp//6YCoQmm3LHEDz7z0d+eB1KmkM0rboMWikaMS+uC1KFwKdI5Bys7ONTwLOXERMZ7mIfDEIf5z1DmHbiICJTRCMgE0QF5h86nMY7P900zMTg1Zib0eGUWnlMLzOHeYyVa9OisxYwfFOHn/7zCksmTSQfh6mNupvcEo0oKn2bDvQOtLHwdOqWkdLt+oNGCi49OAQBs2gCRDbrLF4T9bt9KsMUhfNv3obx5+GxME9mycDN6PTcL/7QoRmrbDEzOmmyDp+fPmAblMZNrgBaiLejEo+B+Wx4wwST/Y4OP092CdxbAMmVvo7DaJv+M0hRKFf+e9oGjJpz2zmnU8SwBOkpCJhJmNlIm4EWaBfjHoJl9m3pBlanDi1TTf0QCMMWXUbIM/tPHY7UghJRMkzz/YXGfyI1g3cNh3rr+B+Yf0yHfwAjBO4Lyccm/wAAAABJRU5ErkJggg=="},{"id":"EsriWorldImagery","name":"Esri World Imagery","type":"tms","template":"https://{switch:services,server}.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/Esri","terms_text":"Terms & Feedback","default":true,"description":"Esri world imagery.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAB0CAYAAADAUH2QAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAActpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgSW1hZ2VSZWFkeTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KKS7NPQAAQABJREFUeAHtXQd8VFX2PjOTXkgICSRBIKH3DipFQEBB7H3tvfe197q49ooV1866u4oiFqwIWOhN6b0FSO9tZt7/+27eGV/iIAkk6P53zu/3ze3t3HNue/e9EQlRiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ48P+TA67/xmZZlvWbertcLuu/sS2hOv+5OfAbQfszVddWBK0jTac9WFWpJKooAXtIeYKxKuRXHw6owNUnbpPHccwMbhSmCkFT3ayD1llN+pECCuGwq59f/ULKQlaFqL4cqCtk9U3XqPFsxVAloOm0ax2dptqd9XDOHPRX5VCTSqIwfiFlcbIvZA/GgWCCFixek/g5FIMK4QFUMVgvoq5b/V0lJSWuuLg4RDHkVA6nQqhdTZ1JaPoA4w4pSg0T/+y/DnlhVS30G/uvSekPURBHQ1UpqAiqDGrfkxlQEqTR+qsC0FQlUAWg2wmNo34ajwxnWIj+ZBxQeUH/sK8CBH/KT5MqigpYoNCmtNgNZZlsmIJuVQb1oxnmiGP8q6qqaLrBKHd1dbUrPDxcYMJLBHY/oMLuNL0IppugnYqh4VQItRvzQIxKKDNE9eQAZIb9zT4T2Llk6ABQXrbAPxcm/T2ws/8anQ6YgtjKYQQdrTCCDtOpGOG2P00qRxgUIgINN24Iv9ZVR3ma6geryYvpyExVCprUIKepdjJUlcM5m6iiaDmIFqI/ggN1lOMu1OF8oDXAfs8BpgL3QEZymkpJnAKGspqG2FDkTKWgAKtdTSpAAJgRorxebyQUIgyEIEMMj8vKykoCWuzcuTMBZhzieqKjo6tTUlLKW7Vqlde3b98dHo+HCqBKQOUgqupA/WkyrioKzQDA+JCSgCF/BHFAJf9povz3gRP2UI+18B+FuNspZzDNbLOHuA32Dkhgg1PWI4HdOFUEp3KoskQgGwMIezQUIwoC74ZyMPeY9evXZ3z//fc9gN7ffvtth7Vr1ybZ8atHjhxZ1q5du5KYmJjSqKioyk6dOm3u3bv3bDCo2ufzUeirUH4lFKaCgLsSUFPtVBxVIKZhZwSA9L7GZjjyD1H9OEC54WD1V4DKwX5i31B2SBy82H+dgKeBk4FGJxbYJORQDiqGUzlopwZQMSKB6PLy8hgqBuxh+fn5rT/88MNDp06dOvzjjz/uynjHHntsARQia9CgQbsyMzPzWrZsWQYlInMo1GSULpFoUvjLbdBeCYWhYtCvDMpSZtvppj+hM4zOKMyHnWNml5CSgBMHkCg7IBgWZWUR0AtgX9DtJPYT5YZ92gtpNiBNo+5HmkRB2EBUWGcJmgqnYkRBMeKhGPRzr1q1qus777xz1IMPPng43HGXXHLJzmOOOWZt//79c9LT072WJbEbNqxPhAI1W7p0afz27dujKyurwyorK6UCELfbn9gsvhqaVtGmbZviDu3b56alpe1G2p2RkZHZyLMEKMdMVe52u0ugKHSTsaowOruo4jmVxBtSEnDqABHkxyyVYLZBkYuBFoAqg7MWHBxVhsegj75GmjCYVKZGoboaud+Z/o5y6IwRhUJiKioq4qAcgucZqU888cQp99xzD6fRMJjrLrzwwmVt2pA3kgL0BpJeeen5hEsvv8rdrl2GPPPM09K3Ty+pKC+RysoqqaqskPy8PFm9aqUs/PEHueOOr5mWZB05fnzhkWPHbh84cOA6KNuq2NjYLPhHYFaJhlkMRaGCkg9UYo5GBGeeWkxGu0JKAqYcYNLZvT7FckVAatR9Y6MqiK0cFDCdMWiyDCoHFSMKI3gclkex2De4P//888OuuOKKKzdu3Jhy+eWXb/3Xv95LuvLKK3di090N7WyHwSEGaQyVuuJpWqUlJYK9iCRlDJCqqFjxWF5JCvdIUmeX9D/cLReFW/JUdamVvXOba9mSxa4333w78YYbbkhE2h5HHnnkyOOPP34lzPlYqq2BXzhOyqIwo0TYJwKqJByVqCS1KKQktdjRlA6w2iyzsmEuREFHA1z+cknuJA5iHOC2AMvsgEZVEJ2e7Lz3z0BjVCF0RKabjaJycK/RDLMG7XGPPvromTfffPNfunXrVvHRRx99GQ9KS2s9YtfO7VbLVqnuar8la7cVysJ1edacDUXy065yWbZktsvzn1vM5sDMuie/KJKQjB0EZDkKRcaHyZCW0XJEZoIc2jlJurdtZjWL8MrObRutTz/93HX9X28y7U1t1ar6pptvXnzqqad+e9BBB61GfbBKqyzCUqwQdi69SgGOSFQSdozuR9ghnEkatROQZ4jqcICyBD77YB6MoJ/sYC5/OQCT2AdUDtIViPsC4jbq8ooZN5qCoHKsOBVDlYNmQDkwczTDzBGNpU3za6655vpJkyYNv+qqqzb/7W9/WwLdyCwqLOw2YfyY8Bff+Lfke5tZr3y7Qd5cW+ySSiw9I1DNKI94IiLEt22FtJ75uMRsXinWIAwsI67EPJMoPijJLkQtrcJPGeSZ6ZpHyB0DU+SUQ9tQWaQgZ6f14YcfWZdceplh8uDBg8uuvfbaL88444yvUNccKEkplKQA9mJAlYTTvCoJFcXYQ0oCTjQxOZTkFBT1BsBlcV26H31xDz0RH9bGHbwaRUFYMdRPlUMVRJUjxlaOWMwgKRdffPGt2Iz3nThx4spbb711G9L1BVKKsHQ6ZsIYa33fa1zbPW3R2ipJjYuSGKzWKv0uyfH6YWLQiIRs528V+QwnexvniPSEkoy7BqxrJm7LL/EulzRDlHAMMFleS8oLMOhU+OSMPnFy6zGdpFdGkmTt2GY9P+kl/0MPPcgZTrC8W4u6vNu2bduVWHJVRERE5MO7CKCScBPvnEmoIJxFqCwhamIOcOAFr/0w26GoswHKCwc4LpH/ibAlMJtEOZhvYykIBc252Y3AJjwa+4xoKEcCZo4YzBxJ55133l1vv/123yeffPKX6667jkI4AIjelltlPT5trTx12WUuOekM6dDjMPF6S6XYXSkuyGp4dJ64wyvEb0VKSX4HqbQSxJ+/TfxfviCy/BOR4ReL1WccxBbK4ALvwrDlASJgbxUeJpHRcbIua7fISw/K3165Xa4573iJDRNr5syZvlGjRqEKEjZs2LAiLPsmH3LIIT9hJqnATJIHfyoJl1ycRQizxFKTHQd7iJqYA1COPR7dUoFQPKcOLrkanfZbQewKctaggqiicJ/BmSMeypFA+/XXX3/TU089NeLhiRNX33LrrRQ8Kod79qqt/sOm/ewWq0haffWWRHTOkOhBfcVlbZHIuC3ijtyEuSBHvJXVUlWyVQrWXAMki79ki/jWYfDYMBvZBCc2LrxVolTFjpb41m2lRfYy2bTqa+l57v3y7p0XSq+O6YKn8t5bbrnF/+abb0YkJib6YE7G8fKXdZTEOZNw5qCihJZawdneJL62nFEZdFBSxWjSmXy/FASVZnpVCioJwaUVT5/iMIs0xywSAcU4Fwpy5o033rj57488koM5sz/CXe8snmadtegBV9e4WGkZWykrpmyWaJzCtjslU/yVkVJdEillO8OkaK1fchZWSvncFUj2K7ladhJXcob4V2Gp5ceeut+JIu0HmZnE5fdKeHW5VO22JLPNPGlmzZZd22IkvihF1q7bbDK5+aZb5OSTTpLEFonVL0x6wY+ZjXWXGTNmPHvEEUd8aytJLrycexJuFAMzCUaufe4gm3/koRNwmg0oR0SDxh4d/6hy2TAn2fWgoGv7tb37zFNn/o1hZ8X2mdBANk6XVlQOHudyIxWH/UYiTqwivvnmmxGjR4++d/y4cfn/ef/9dbga0g/hYW8s/I913opTXIfFjxAfsnHHhEnuD1mya1aBtD81U3KX5cnG94vFyuYzvnKJ6YwDq979xd38dHE1aytWVLz4wmOk2h0upavnScU7N4h0HYMDwZuhnokS5a+SiqoIObLTSunRcar4/blSVu6T8iqfbJpVJrOfWo58a2j8IeMkrXuad9rHn7iKCgs8LVq0qPjiiy8e7tmz52IoOa+y6J6E+xHnpl33I/We3h1CIfVVLqQhb/2Ir6OnXfOGGciHgxmyqd+DNDv+XuvpaFMwPlDGWPdAWH3z1dYhvipRIA8No+nki10X+sFqBnBjd8ZviH2fFcQunAynUugsQuXg0or7jviioqJ0jMSPz507t+WWLVvm4eFfT4THvr34I+vsn493jY4/Sqo81eJx+8RXUCFZs7Jk3csbEYXUTFoNL5LUQ5HgoPPFFTtcvFYX8foSpRrjS7XXJ1VeL2BJJewFc96Tqk8fFxl5ucQMOV3KKsJlfOdfZFCvG6XKl4kNfjyGfb943R6c6fpl3mtbpGxmuGTe00zSKvpL8xVx8tzL2PjXHOl6xo4du+ODDz54AC9lbcMdsUI8J6GScD+ix786i1SjM/Y64im/EJfpAgT/g+BoB7QC4gD2CRUxC9iI+NthGkLcfVIUpDMC5qwn/NKQaQZAMxZgHJa7C9gMbEF8I5DB0iPcEMIQ7VfhV/9gJuPCn/sJwwO4+XCrO4BTGbPq4FJ2LbACcTj4NIicdYHdbO6ZgdO/QRkiMhm+r2Qai8RkLMG8OJtEonFcYnmee+65k6AcrSZPnrwGytEGfrFzNi70QzncYxKPFJ8Hq5X8Mslekiu/PLYawSS3dD2nlbQdliVRLS6GSE+Q6or22H9HQzm8EHIoFHw96BO3m/CJCw8KEwZNkNy1cyVy5gtSljZQevVvLQO6ThbL3xnporFWgXrgNMyLGcQV5pYep7aW6e8tFdfsHGl+foZcdurNcu31V8rjzz3hfvH5F31ffvll+rPPPnvcbbfd9jIOGGKhIFQMXV6x87TdbnRArRESYbWInQUPSpIKxmC4TwBGAl2A5kAwykPapQiYDvDEZgcjwW+Pm1aGOwlxA88GYM9A2GnAeKAHkAwEo0J4rkL8r2D+B+XqSVEgLyZCuJ4wjYLzbIAKRrlwEgfQSchjMUwYLlwbsjrBfiWAI0jzfgeMWjQBrk8Rz5QH81q4+wBUIA7GVFyCeXMJ/ADyLQMQ1aLfyUBL2DfB/Bj+fJ4Co36KjDQB2icFYWHIQQVEFYXKEYHZIwazh3vhwoV93njjjaNYUmJSc45ScZtyt8s5C25xD2k+XHwV1ZKzJEtWPrVavKV+SR4YJ5kj0mT+49sl4+BESW5/t5RmjxC3NxocqRJ/WDUUCjOHL0yq/X6Ylnhw9Iun4OLCS1Phic3Ff8TFUJI5Iu/9Ww47pa1ERRVJSUUL9Eo1OhPnAKyM24VnJpZEJkTI0Oc7y1eXb5ENGVMxdCfLK6NflEnPPO8P84T5n3vmOc+LL744Zvz48T/hGv1CzCJUkkrkQOVgW7nccfLAZA+/WgReBYQKdvLjZmBErUg1DuZHkJSnSbCPsnEn0j8N+8Po6EpnvvALShoHJvN5ADgX4GzhpGDlJiDCwTZuQ/p/wX4nyl0Pu1M52X6mp8KfD+yJZiJgMdLzuJbCPhHgakOJMzD5p+2mEjjpDDhYRjCi0jwKUDlJw4AOAJWf7cgBIBQm76B9hLA9Ehu4L8SGqHDQpKIRfI+DG93of/zjHyesWbOGdl+428Op1PXkkldkk3uxuNe7ZPET82T5Qys538iQu7vK6Lt6S/dxGZI6qEzyVpwirqIJEuOJkrjoaomNcktsZLjERIQBbonBjBEV7sbDc9pdEhkWLjuqwsTbpoe0PgYy4P9cCtZPw+PvZHCdCysXFMQedsgi1NiLB4rNOyZI10tiJfOhjvLGxlfkxXmv4ZTY7bnz9jt9GZmZVVgWhr388svHIQXrzw7l6RyVg21lu518gLM2QRh0BEyH/QOEfgKMsGNxNiEoYHatAnykgNCPYRqPs8y9wHzk1QXCxpGY9QhKjrIPQYTFwBUAlUPzq2+5bOfpwHLkeTLK5WhMPydxdiVxANH8aeoyyYQj3UvwewogLxmmisH2KmA1S1maSpzRSM78OZuTeBxPXimxrzYCzG8ZQL7tM9VtaH0zcgoG82BlwsvKyihAMm/evJ7PP//8kOHDh1O7LQusmLtzmfXMxvtkwHeZMue6WVLwY4n0vbaDHPviIOk8sqXExUH4w0olrSsWwcty8OC8WuKiXFCAcImlYkApiGhbOaKhHNFQEr8rSsLCXDI+dZ1cPnCqnH72BlZBvnjVL0V5FWY55YMoUBr8mPiMqQoDtrY7/CBwc530WdRdbt/xqCzfvlrw8lX4pEnPmw54/fXX+3333Xd9MXu4MIuwYzmFUzDZZrbdAJ1PngQIblUOCuh84ASAxVNw2KGaB/0oKAoVMMZh3oxHMB7r1AuYjfx77klJHGUPRNxvgbYA0zIPzY95s870Y5ksn3btW43HejAt2/5v5H2hPRMwvZLaNY3TZJwCpLsU5iWAlsWBhjysxTe4SRU1RuCX8Ug06+ZNt5PWwJEJ/AiQV7+exsDRUNKG1TsdGqoMVAZrpcPxBJozRuSUKVPGwXRdc+01m7DrdH0672t55vMXXPKEyIJnF0r6uGQZ+8pA6X7MQZLQIlzCvOESac2SCPexktLuRdk8e5K4K4olPiYSyoHZIwLKYVAze1BJqBy4YygdErbLcd1elqFdLpXk2EmS3KZCxl/XTrJX75aNSwu48IdioPfR9T5YsDoDYKKC3mq/RCRFSt87u8mOF/KkZOcaeXv9fygQnjGjx7hP/8vpOIwrF2zWR8OPoy8HALZRZxHywskPODkiBJRjPJxzgHSAQsa42qEUFHXTj3xUXtJN/jIO60Oim8rJfFKAGSjnIFtJmM4Q/Lgv4OzCkfSfAOvMNEzr7G9VCPpp+bQb1sDUcrWOTjeCa5GGOT3px7TMbywwESDRT+vLOAxXwGoUVWekYPkyDknD1CTfufzDskQmA5uAl+DeBH8Y+3YCqJ2FvOpNbKATplOx9+Dyyp2bm5uO5x6DcN8qd+iQoWG9Dx7ieemRZ9gIppGeN3aS9sNTJTbODcXw4QTLgyVSoYRbw7CXOE5ateGSEXNpznZJa30Q5mEfhNwtXgh1tc+FLQQXTDiN8oVLq9id0rP1gxIR8RNOqgbjuNiFJ+8+6TIiWT57arMsmrZdWvdvIR48Nuc5E3YrYtgEuwVQWXzVliT1aiFLZZX0XNZTHkl+ynXm9pOld+sukWeffXbpP6f8Mxob9l6rV69u36VLl2WYRSIxm5BvKlTIKcAPp3L0gf+HAPnD5QQFlEReEEzPtHOAhcAugMS1c09gOIDxxRAFSIWb+XCpQaXjkmUCOt+5CTV8hv+1QAfAWTachpifCukO2LMB5t8SaGXbGYfkjHs+ynrdVkLuJ7ROWmZNippf9WP6qwEOMGw3y2W7SbRrPOOBH9ZXFUT96muiSkYZ2CaC/YEqN3xzrgWyk/aFyBgFG8l82HEunFp1gxl/3HHHrUxKSkot99W09aCOB0nalSmS2i0BQzA21zhNCsfSKJIK4l6AB4PTJczTUlqlkYciu1cvlu4DDhFfVLgZ+asxBXjAS7fLgyUVzrHCoiQl5gdw/FvJzh4tlWX5UpiLh4mlPinOr5bkLpGy6cdSmfP6RmnWOkYiEsLFg3ezwrA598SHi4vvaWFWspBneItI6XpbFymcWISHjTny5ZbvqCCeQQMHeVokJ1etXLkyAq/99oWC/GIriC4PlAc0eYTCEYyjN5cj7wDkiY7esBoBocn4/wHuQ/yf6VGXkEc7+HHfcDPA+BQqFWrOYnQfhXinIg9uoj2w8xVhKgvLPwsgMa2TNB/uS+4A5gL5AAW1BcDN8DXAEYBTOS5A3lQO5yYdUfZKlA2ipmNrt4OJWTaFhG1i+TrjwdpwQh1RxYDiUju03IZnhhT7oiBGGOzSaCfCIDiYQMIj5s+fz3Wf9OnTx4dXZhMWL1gsaWGtXanXpUlKl3hx48qI2wOh9IRJuAv3pTxfiOV9ASP7AOzwKySqeZIM/csVsmDaGzL6lHNxEsXjXb9Y7kjMEnikXVomJTnZkrdtq2zPmiWFW/BO5vQFUl2u+ziW/istnrLzV4fDltAjWpL7JEl8hwSJzoiX+E7Ncfi/RVpuaCtT0j6zzik+1YX3UsKuvPKKqvvvuz9iwYIFPS644II4TB4c4VRBdASkcJEPJArgfUAPwDl6s6MIxrsHHXc/TEMUOlh0JGUcHhtvhnkLwmbDnAqwryiwWo52POPwKFY37VyWsQ86AySNT7sqB9flw5GGe0Ql5seZhAcJnyDPG2E+CpDORty37XqyDg0l5k2wLmwrZ8y3gB+A7QAHEfKUsyLrXbOM+FWp4FV/Ql33pY5BC2iQgoBB7MS68OAGbBiemrPhcT/88EOHc845p/LHH3+MP+WUU8gQK9+b78qMa4MVNWYO8CHM7QUKoCRLsMT5u1jV4yU23A8/zMN4XaRLv4Pl+ymTpDw3S9J7DZDCggLJ3pUlm9askJXzZssP7z7jaExzyTykVNK7pUmztGjc3wqX6BYRUCqRmc+vlexfKuTIv/eQ6JRIKS3ySklulZTihm/e+mLZ8F4WllrsH1S8fzOpSqiS+AURsrDrh65V+XdKSvyAMFyJZ+fJL7/80gb3tlJSU1MLsJzkYMD2sn0q2NyUl4JHHeDHkZ/EOEoUTvJ7MuLdb/OS4WbU10g0GQYwjKP1dNivg/05hjmI4RS6/gBH+88B5k8FyQRYL1UIWGvRy3ZddbRmPiSmYZl8+PkYyuUSLw/2gHLArnEZXymYn4bRZDh5RboNeTxcY/3NbxZ8qDy6NGo0Qf9NSfX0aJCC2HmSiQo2mptC5uPatWsXP8nTavPWLR5c+kt9Y8rbMufn+a5XHnparBwskdLxTgcuIbolEYLZBU+0/you73Ac4YZheYXnGsgWe2/p2KOvKWr9ou8lDJuFH7/8WD6a9Dfjx5/Ow4+U9H4TJL3LdklKf00i4wfjti/2JtAw7kO4Kfdjlup+dGv57pf18LOkeacEicET9OYoA3tzaYNnIV3O90lpXpUUbsPDysU5UrKoSCq/wmy/G8oV/p0MP2OAp3u37myrf9asWc3x5mM6FGQ9Hhw6FUSVhPFIFwFcb+tMQz92NHmEnOUWgGQ20zXW2r+2EHKpZAQE7udhPwexuPxRoWd5VAbmezJABVFBZfkkdde4fv1l3WqRXSbjc29h2gK/exmJbhDL3RNp24OFM09VjrOQzzuMhDxZb4Y568h8WJYXcPrD+zekZar5mwiN4cFKNoRMA5BATTbcgxE1DBLj2rZtW/KyZcsSTj/z9IpPPvw4LLlDury0kstjnNvt9iJRllSWn4v3yIfixCpJosMSJS6SuwA83UY/R0ZFYV8ShiHMkrbd+sg/7r/epOVP254DZOgJ50lq1/4S2SJNqtxx4op6UzyeQlyNj4DQV+Lho2WUgadVmJ4kpXuiSb9qRpY0795cLPhxL+NF/2PYxj4kTKIPipCw1nESP6ClpBzZTtb+bZGkVqbL3Wf+VZLyIuWMM89wH3XUUd5PP/00YtOmTamHHnqoG8ssM7ojc1UOmhXodK79jzeF/ioUdFK4GOd9dHyuHa/aFhKG75EQJxxpuEafBlBBnIKjwjEM8biGN7MdTG7iSRpe4/r190rEZ110KUOBZZsYn/mbmwHwM/2MeEZRf03eIBuVmMsnzlrvIE/KHPOn//6Q8kHN/clrj2kbqiDOjAzz4IG2YucMysnJSYbhPuWkU8o7dO4Yty53k/wQMc2KlRauwq2LpEXBA1KefwKObSOEjxNdrip0DM6W3HiWgRPi0vwc+fnLmfLl609J1vqVzFJGnHCmDD/uDGnVsSfeHEyQMgz/xXhjsKJyFx72fY08emF49ppeJaeoauC++PGkPRqv37Y/OkU2TM+WojMrJa5dHJTJb+JwCYZFOxTLJ9VUGKSLbBsnSUNbS35VmaTcNtrq3a2vKx7HbZ27djEKgg9McBPJ/ZYHSkKBVwXhsoRPtw+FX1eAxDAlwx843qUH4lLg60sqSN/YCZgXm0r+axkdYO+IfH+BSdpWY5hwjUsvpqWwc4/CB47cY3yKdJuAWjMEwhiXZeyPcjAtlaME0GUVp6P9yRNZHThqqIIElAJVVLsKihuf5DFPLfE8hEwJyy0r4nNMV3O84pc1D9cPBx4qsQlQCBdffgoDcLIUHo27VmXyy/yv5LvXn5Bda5ea1h884VSZ+8m/pMfBI6TPYUdKQTFeoCqvxOyDg19cN8EVRahFLuJGcfRDL9Y8LSfnoRuIgwpGeiR9ULJRkOy1RRLVJs4swSgJNeBMAgmggiCRF9dQojDTFNy/SbKPL3N17NUNihvubp+ZaYSnsLCQa3LoRi3lIB+UuB8gMT4FjEQBJY84undGXckbrv3pXx9iWm6me9uRWZ6mpZ1NZj92AlRBlsFOJTkIYLizjsyP9csAnge4byLT0UOyAODp1loIcWAZhnDmz1G/oYLN+CzvC6TdiHy4rDS8hN/+krZJzf3NL2j6hiqIZuLsIH5EmpX0YP9BAeIIaUaf3SU4wcNquNmwlrLt02wpzyuS2MTWRnglKoIRJWv1Eln52VuyasYUk/fQ0y+Xw085X+Lx1wZUkNmfTpWuhx2FC4lQJI7+FGYszX1+LKvwZqFYZZCWcAg57ltBDrCANhLBfQdX8HHt4k2+O5fkScshqbjPhQuL6CIus3AR2M6PEsN8ETUlCtdbk2Vzzo+yBYcEaQcluWPj40x7oSBcxpi2YVnJL0Cy3c4OopCSlD+0azgVYzI9GoE0T2alQtiODgghL4vmw+Ta9gaAgs56O4ltoKCyntyvDLEBwxy5rkP6ObB/BnyD/KigzLuhR7xaz5+YHkRlaaiSmYRBfpTHagaJsv9erHBDiY3WhjOtul18zdZ42Arir0Y/oGsiO5uJRcp2rOJBllh4HbYsP1uWT3tNpl53lFGOLqNPlvOemy7jLr9LWmR0wU3eVBl/6W2yfNZnsm3zJqmGzlVAsqsgxVW+aihLMzwJPwy9/z0UpRLgUgl3fbFkqzLKAxMPAcPxpDx9XIrsmIFNODbkfvPQkQriUA7Yzb4EebuaRYmrLa73ZHXFO+5mr+uKisBGCeT3+8kvwnxZnibgpDSno46dcZmPgoKioJ/anabTn/ZgpP4pdqC674d7LUDl4J6E+TqJSmJmBphcxhFUGvYhl2CXA9OAn6EYtwLRHP1h1ndQZT2UP9tgbyrSMpok/31REGdFalWOa3MGlpSUGX93RQYeXFwlkRlbTJp8vNhUXV4qOasWyvePXCLL3njQ+I+88Tk5/KqHJK3nYPMxkvzCInxnwSVt+3BJj7fzl8yXskov3vvgux9+KEjNbd6qsmOlvHwi/JLgFw3FwN8hWHlQAigiFcaLGQUPA1v04dYBL5hvL4MUYOaAqHAmopLUALMHwunv5+aoMyxLT8ZN4iSTrubbcpC0yEhGC0oQHLY5Jmjgr56MoyDvFfRTu9N0+tP+e2S0GRF4CsWRvhD2Y4CNAJWE+aoiqBLBy/hT6An2H8PYTs48VKoMYCKwEPn2Qb76vAVeeyWtsx4e7DVBAyJo3s62NCB5/aKSKQ0lVkgrZUwoBhfmzIcMle3bd5jKh/GjhWuPFFf3XRLRY4uU/LBUNsU8K3lfvcFo0mbs2dLzmPOlVbuO4sO7HUXYZ0TipCkcyyCrAs8kWneUWJxY/TTtHckcMh5vHcbjjUC8m25mEcwmVbF4cn4ilGkUPsBbAX8fBL4U11hWS7OkaVAUXlPBfa72NcusgvVFEte7hVESnnQZ5cA7IpQGLq+gd3hC7xJPK3jM8eGuF2uJzUNVTf/im8C8RIdTXp+2V/nAZSXkp+ZY1iQK/sOiAmmCR2mwL/Pk8s2uLTSwZqSnkqxGnQYg7EHgAoB7HyVnXZhW07PvqChOZWHcbsAs5Dcc+S6DaQZD+JH21iYV5prYjfO7tzIbpRRlyv5kBl5hwQ/ZwpqcU7nk5+eZfGOjIHHFLaS48FQ8sWbI5oBydLzw79Ll9JskslWGlOJCYBk+IVoBKS3HKRVPqorKkBVenR18+lWyc+UC2bJuJZTAhXC8NgtUAJX4ikkVTqEq/UlS7k2Xoso02VWcKT+tOVw2bTgDG/pyKS9G30ZHSEzPWNk9d7dUFOL6u8eDvQivq+CgACe2OHSHsnBm8WMZ5ZIydx9MNztxIdL0qx8KYtqD14WL0Qi21Qk2TKlILXswKVQcSRoTKvRm/6flOpQkH/Yr4c9N/p3ADwD3FM66sH1sE2cYM8jBJKmyYMNolmnNYL6F7uY+h0qjgq8mvA4YHZAyzbDfgCaRiSRWzikkZKovOTmZx3myY0cWwv2S1hybaG+u7P5snhTOQKLoBLHK8yXzmsmS3HsI5nA8qCsrw7sdrAY211gWUUjDIaQsAM/cJbnbQGYpa376RuIyepnZgw/6qvC/OlVuP77PW4Yn4zuxv9gtJdnb8R2sXeLO3ikrsgpkW/Im8fHUC1NF1dYy8Rfia40vrZAYPDT0JEaJJzlaXIlYfcTjdhiOmf2Ru8RXPlR2l2LPmjxfEvi1RlQsOzvbKAhmEGxOarXbhPPHpm1qcZjkE5vDaehNgHlwxFdewrpfRN5TOb60cwkIuK0krDusLu5HHiIg4J1h9gMOBjjD9ABaACoPFH7nDAGnWaZx2UVFOxN4DWAc+v2RRN42GSlDGlKAKgbT0M4OMbAFSKZ++JHr6ScfE18ZZOFVfPnQfDoVsSKx/4OC+NxhUl6Jp94Y/S28DMXkHLnxYhWeqANYbvE9dTeWTeHJbaTNsGNl+b+fldbDjpe4Nl2kpCBPinZvk9wNKyR33VLJmYO9ZBWX3L8SuVa0DusGjH2uxHhxmW9UV0nxnFyDX2OilzvhMuPAdhLWaaNER+JWR3WZjOwXbzWLi3ZZfq8fX5Mnn3wZGRnZMLnGpwARbLdT0H+Gm2QUqsYa+OUo/CQEdUXAp5EtqBcVgXUKkLoRRmFmOJ9Sr4GdeI8REcZFZX9gPHAWwFMV5lO3HSqMJyHsNYA8+KNI+a5mk9RjfxQkoBy2wAhu72ZzI5uXs8uTm5fvXzR3Nhi6Ba/TjpRd/c6X8K2LpfrzpyR3yde4HNhSovAuhzt6A66IcGUWBSVJwwzCY+CWEFJ8HK4co3xEoqQPPVG2Qgk2zv1KEnbtkE3fT5fd35m+DTAlvOcYXGXpKlZSW6mOiBcrFk/RXfGSmr5SUto/I6U728i6G36QuHGpknw0PuJQgL1MEW7/biuVyjX5Uj5lpcmrWcLdIoUR0vWKI1yxEOnCghLfP6e8GzVixIhcvFZPBeH+Q5ciygPtpEUI5j6Fyx4VMAoV45PXJwArwC+GN3TkpYAzTy0L1lq0xwdwtnLwOQas5jDBzCpIzTS8C7YL9s8IhD8C83VgNFB3JlEF6YZ4PNUqRxzSnupUE/pf/NtQBSEjlBlq596DAmB17NhxF65iFMycObMF/h3KGj1mjIy94F75MrIP7ky1kyL7FnLpzHfEfdpSXDMvxU1e9DpmFD+eS7ndxRjioBS46e3ydUaWHVFYN7zUVHM4tPpdHqbUEHsqYeQ5Etm+n7hTMsUXjQ/E4Yl8OWYiC3sZs1+GLOwoP1hi/adJ+EFfSXivdClbkYMFAvJMx81iLL3CsdCoxh2t6uIiKf3lSNm+LF/aZn0gL056Xg4eNFDwPrppL/68Zzv+OqEAG3QKKdvrnEF4/EmBWQlzPsKGA6ogsJolFs2zEP53xOO1FD40Y5y9EuLyIiSXaBzt653Ojh94doG0ag+M/PAjKwkqDfPeBr/TYOdsmAoEawfWzvjsTM0zExiB9tF+oEiVtUnLqzuF1rewgHIgAYXDKAheVc3p3LnzFmYye/b3VqtWqXL7DVfBlSAJ5RUS2wnXPY5iqE/yluOjbt4O2FNkAm2A9nD3wca7I/87TazohbgWcodkzT9elr99KtLU7EXDUztI6ml3S8Yd06TF0VdLVM9R4k9qI5V4f728CkfBFRW4HYxBHBt4lx8m/hh3w6ox2OB3kNj+1eLfUiXlOTjxwmXFqgocGXux1MM1e1+z7uJrNUYSxp4vWw65Tfp2dkvv3n18uMVrOoL/L4JKlOPErhozCEd/ChlBXlCIOMKT3q4xav0yjHG7ArfbIfwaiqaxvWobCGccKgePVrsAzahUMH83nebCeIjP/hkKpNt2LvUCBD8z88Dk0ot/W8e7X7mIMM+OFEyJKTfOOphBJJDpgbEckDIbpCBkJtpOhtFUuw9XS7x4NZUCUNq9e3ezVvngo2mukqICq3c7DDQtwmQjnmM0S10tMQN5JB8tOz/LkrK8UvF68LwCH3mrwseqq2B6cau3GrcxdiwLl+8ebiff34+vsi9HFv1xkREr4+qd2yW6+3BxtepgTrxK8H5IWRlOq7AZ5zEvpiAAzQLwUSAsbPDNLW8U8k7GpcSa5lYWVmEfhFMr1MSLZ39ef6FU5XfHA5wwScLeR/I91sln3SH9+/ernj17NjfU/gEDBnDNXo0/3OFI7pxBlB/0I00BNgKcnckTJeX1fRDCc22BpPDyRacw26Q94EYcLouoHCOQCWemt5gZ/Ew62vdEzNOONxJxZgN8nzwWflQCLS8wCsOP6y8qhy790u28A3HgZp+TygBzIGNcqJJt/hFGk5atndaQhqliqEkB8WJUpeD4hg4dugR/ruldumi+Z+nyX6wkvJ/xKF57FRy3xuK7PZ72XSWibwvxbSyWPHw9sRq8rcLxbRWWRl4cuRZnV8rK99bLDzfMl7y5G6XlCLcMfKi3DL67l3Q9jw94KyRn0WdSXFIqZZgxKrBMKucpFZdVwfoJChAWjhMsz26xEmv6vDIfT94hunrdpBoDsrcyBQcDbinB7HVI1xhXbEy0bN26reqll16KuPDCCzdi+bgZhbOtbGfdGYS8oNBSwIphvwtQUqFiRzI96XXEfQRIpBADHL1pKowb4ckA15UzAT7MORbujwFE3fNTbYSzHlSsMUjzJcCyhwAL4DeAYUwPmLrZ+TFToxxwX4G4PD5kuFNGtC1rELcI8XQWUX9EP2CkitGkZTsbX9+WsUJOcJTk64TcaVtYiqzBl9LXMrPp0z81o+sxg1vjYDMMr8S2F3c8PuMzFm7QzvfXS9luXDqMwLeu0A85y/Nl/p0LZNNb+HB123DpeXdP6X5VL0mCgvlx5Jo0IB6vzSZI8UdPSGnWRinHrQc+OOT76kGJ/Y99T1hMHp517BB/LJfOnIXKjYLwFi+kCDNYuDRHXj78TcIwvH573eh2iOWuXrx0qcl4woQJ3HwX4Vu9VRgI2E4z+cA07YPJeASFErJj3nngTEIBMkIHk0R+q5LcBDuvcTwNnAAMAHoBBwNnAC8zHLgVIBk+wzwamEoPlMPyavUh3fDnVfpRiPIpwJlM68sl3o8IewroD5jlFuLDamaV7jCfRxxCSQWRbsMPmF/YgZxdSc44NT5N/6t1adKSajG3PiWRmYingkFTO64ayyx2RBH+4mwmTHn44b+51q1bJ11aJ8idQxJwhb29xOWfKJ5e6yXiMHzobUul5PyYJRXFXtyV2iorb1ss3q1VknZupvS4b7AkDm5plKes3I/nJbiv2zxaOl2XzqylcuFHeBCIW8FG5vbEK/QblMAdha/DYz/iDY8wN3z9JZhBUHNMPGYW8eMBeAqWdvjnHjn34FSre9tE+XnlusppH34Y0759+8KRI0cuQZFeLK94alMFUOjZbicfzCkR/FRYLoad6SiETKNEnrPC5BVHimuAD4AFABXxJ+AdgOlbAYzHcqhsBN3HQZD/A+DvUMyexJQJt9nAw+Rx7XSAAsz4VBJVFPpdC3DJthRxvwa+gp11XQxw9iCxjtoWupkP0/Ik73WAxHr9UeSsW5PVocEKYteEzFPhCCgIRlcKkHXiiSd+j1F3G+yed6e8x3DrgtEZuDcagevsY3AB9xaJPqIzvPHU7J0s2fDkYtn50lrTG+3u7Sstj8vESTy+7A7F4BIK/xKCPUoYNtoFWKKNw5vLJ4v1w7t4MI8+xUfjcLRj8qr9Az/TxXifHV9N4TLO60FzByWJf2MR7oTxLRLc1cLSLgX7kdX4h6oeHWPlyP6pLn4WaPLkV8OAcPxN3I/NmzffhqfplXb76s4g5IPygqO63oXi0+qxAAWfSkIBIy9I7FwKLNPRXxtAP5L606Sf9pMKBdPwWcSFAIn7FhRtyo6C+yUgBuBeQfOE1dhZFtMzT84ohwOjgR6A1tNwDm4lxtd8rkc5WSiPysr6kbT+Na4D86tlKk+apFRlfEMzJ2MIVpIgA/miNi70VnhxHLrr9NNP/xh+cs/dd7qXLFliZbaKlzeOSpOCPJ8kbRkqhdb94hlzNqaCMqleiA84DGkurZ85VKJ6J+MkC8dFldhXQI7471Lcn1RiJVHh3S15ZQPQpSfU9Aj/QKcoB+KBflUlockrUYZ94B1a6MNGvRpvBVfj1V5JicWTiKKansWdL+gGPjmEAosq5Jlj2/Gf3qSyyscRH88+RhZD2efAXolPnFLYcCxmZg+dQbT9lE5TIsJ1E81NMionIwHOEBQwChV5pYpC/qvgBfKCHzud/s7+YRqmpT/xMDAJIJn9BISWMwjreAawA6CSsJ+YTuunedOteWqd6Me8GYfEcLaVfqS7kD/fCmQ52oaakOC/Wmbw0MbxbdIynB1Q7+qCOayUKglNZWQV/iqAgmSdddZZX1944YWctt333f+AH1dCrLMO7yiXDU6UtTjw6rB5t/jmLrJ7Ilfc3B8051EtpBHdVYWlEZWDqMDmvsoql9LKfpKTm4xbjh1EjrwOk/0qfFzy8xqFQEFGBvC1FAnDSRlnFko/LlJ6i7DPKMBeB19atHC8S3IVoyCss9pHRMgOPNp49ZiB1uH9WjKofNeunYW0XHLJxd/gyyab7dmDMwJnDyoPBUrbz7bTXovAI+4PeMxaCnC0vwjYClDYqCisCIVP86LbCebLMMZh/kzDtOuBY5EnP37AEykYNcoJk7MXhXcO4nCT/RGgSkihZ34E82ZZ9GM4QTvLqVsmGIl3pUX+gnwfZHmwM20wUp6oqfHUDJamPn7Mj6T50tQ81TQRGvuHDN9XYiXJaDKXdnYkhYdfI8RHTqKL8PfLb+OYtPuHUz+IeP3NI32XXXqJ+55Tero+v+M9Wf/qOeZ7mFuOu19c2xZK5ZcfSXZijDQ/Pk34QWo3TqVgmF7D/Vq8p14gZYVjsDTCu+i4dW51G4OTeuxVv8V+sm1vkUzMLJWQ4dI8PP7ejbXbNrwDvBnmdvGvnIFqkZabXxcuIVo3zpLWvdvLuvQN5juFnXvhu1Y+vz87Nyfv2GOPTce/TO3ALPgtElTiGLsYJkdmKgjbyXazzYqgnQSB4smW2RfAPhl2ziSXAWcB3QEKX31pNSK+DPBrgXwLkHyvNXMxI4RRSTh7UaiPh/14mFcDo4CG9jeYY46tn0Z+2XsqE3G0HWrCqxY1tNxaieGItj24BFRi+0mcJam0TUL7lTE7ArUiU2gSXP+ywvFYaiVhNol89dVXT8Mfd54LP3wZZLYMHz7MPfHhB+X2277G15b+Im069pOtu7eK619n4VZguURf0kdi8a1eN/YBEGMzCTBrtydLCrdeLyW7u+JeVTn2FShqKwT+jUvxwP0w3CQ6Bi+ZrsBd1X+gKAfFdoQoYsZptxE1wyXIjYVizd4p7U/vLxvKFkn/mHEyNK6jfP/jLOl7yOCqnOzdMm3atAh8X/gZPD3/CU/Oi7A5h9YJZ5USQDfqVBIqCz+RQ0XZI4FP5DNnE47OWA2aDywMhZVCC82WDKAFoJ1NZcwFtgHcw4BZMhvpWTbTm4eHtO+JEIczjh4cMA3vWh0OHAyAKeYLjjw6Zr+x/pwh2c4tAGf+2cAslMk2By0TeSLYnICBweYuF/nBtjoHDNbjR8TbofHhbhAh3TAkSAM4AKtisAzmzRXLV8ifJ3emPnA3GrEx+0yoECtLBlNJWFlqOJUEC31phqfOzbGxjbvpppuufeyxxyDF4l24aJG7f79+7qUbcqXvW+twclQqXZLiZPW2NbjYeLZhbeTVfSTqkFZ4Eo6TK7ABrQbKpWjT1VJdeBBKgWziNq/gjzxl+mPYrM9F1ja1Q/93RVF4kCjNsByLxNINX5CXzH/hzivKmFciaU+uk6zH8T8kbU6U6aPvtzokpbkKiwrzr7ryKg/+ZLTZK6+8Mv2iiy56D8pRCuXgPoLX2DmLsDM4i1DQCTOboH5OgYB3cLL5xRmFaQMEf/KtGUCTfcJ8ixHPKATshhCPvA48v7C9f9dgmiDlsQwwxvQV+40KQuFjmTQDhPQMp+Qxzm8I4Qjae/vrG+83BfzBHmT4PhOZhoaTcRxNyXQVGgoRhYmK48Z/oU/mN6Xef//9jgP6969es3at9OnY0b3mIo+c9sZKWby1WDq27iy5F70m+a9cIJXPLsXLJf0kHJ/iwUqeax90UTSeiGNvgT2DVBXgRayZ+PLt3cjeQRNux1dtx0JVUSz3ImazjrTVcOf1wf58AT5QlyCbpEDOTr3VenDM9a62zVuy3gVfzPiiCsrR6uqrr/4FyvEx/HhfiorBdlBQKThGIWBqmwMjNPz2SraQkWcsk4JHosAzbyribwhxtY8Yr5Zi/SZyEA+mscvjYMZyWWfWH0z8LQWpG/t2j4S8kMQMlDqyB4vbIKWumwHyJ69Y96C0L3wJmlEQzz0WGiRuUC+boexEKgMbQhOSbJYLsVhq8Y88o3fs2NH+/PPPvwP//ZeOsOp58+aHDRo00JVXUiWPf7RK/jYLx+vJsdLJ96HsfPnv+L4uJqLru0hYP0TH931dVnPxbrtCrI24ePr9C7is/T3GwDbYrF9bowj/vhkHleNwYfsGKBFWKnhvvebKiSXJeJ89CX+nsKbNa9iGvC2xz7aSddnLJTU5Bc9SKgvwRzle/C118kknnbQVf/rzJE7htmL2K8LsV4ANejH2IFx+UEmoIBRSMxCgY35XeBCvXmTzkH2h/aEzEodntdcrr/pEcpTH6M4ym6S8+tTpzxpHmbNf9bM1nEpCqJJEQfhicP2dSpIIJYnCH9J0vvTSS2/+/PPPWyMe/jRzuvuYoyeYkefTBVvl/A93yO6wZcjlaun0Ynsp2L5Zsi/vJHIIluf4pyiZkYED00eRFHTMXVhJH4plUxLGRMjr9++I4O/X8HI74p+GDy5Ykoac8eqbbKhA+C5LLhjjkdTSWfLmFU/KxqqdvsLi4uI7br/dheskCXhuswv7pSfw5cQNqHcp6p2PUrisonLoBp2KQaUwitIUwou8Q/Qn4oBO8/tVpXvvvVfTO0dBfW+bph9KEo5/jy06/PDDf4aidFmxYkXylCnvSnhElL9Ht66uPh3TXBcdnCYd8CWRj7GyyWv/lZTNghwuwPvszfDm3y+4KjL1Y3H3mSDRJz4g7syBWElF4itulXiHPUziU9pJcuF6iZn3gZS37i3+5AwpLijHFscvA1tFyePHpcutx+FqfGG1PPfWS1b/AQNKr736msipU6fGnXzyydufAbVu3Xod/gSoAidwVA7dkFM5uASiYnBpYpQkpBzgxP8ANcoMQj45llrOmUQ37Wbjbs8kkfimVMv77rvv3Iceeuhwps3s0Mn73DNPu8eOGeWGwkhOSbF8s+FHmfHzLPn0xX/JztlrBfOERB1zi+zoeTQKw9SA72A1w3MOPg2vwJuJfrwLImuX408FLjHru8yrp8ixB/eVw7vGydCeafjEqRkLvJMmTZIrr7yS7TYeV1111ZKJEydOxr/ZbsfMUY6Zg6dVnDm496ByEDpz0DQX/WCGKMSBhnEASsL3FyKAGCAeSAT4b6NtAX5VsB+U4zCY44ET3nvvvRfwN20crbnOtk46+VQv9ii+0uJibmStZatX4N82a8Jq4oyw0v/6sTXg4fmW3DjTkiu+suSab4w97Z7Z1sUvL7EuvO1Jk9fAYaOt7Tt3MRtctfJ6ly1bXnnXXXdzH8FZwMLbjz5MGh8h/FzgOCjvETB5UbAn0B5IB1oACUAcEAXwmnijDSqoR4j+1zgAAdqTkrRBWCegN5RkCECBPCorK+sKjOCf4P9EOGIb4e7dv5/vueef8553xtlmWQOl8eMUzLrqsvNN+Atvf2xt3V1i7S6osnbmV1rZxV6rhM+UbUJ+Rglu+usNvhkzvqi49LLLOQuYtDRxSrVs8eLF9yL6icDRqMsomAMB3mbNBOoqRzT8QsrxvybMaG+TjIYQJm68nUst3bhzycUTLj4ZjcGoHY+9O/0i1q5d22X69OkjZsyYMRhIgV+A7r//fv+wYUMlOyfXevjB+2Txsl9ck1+ZJEeOO8rlxotRZaX4bm9JiZVfUIiPWldaeCBpPfzww6wDYQjvqFRjr7EMm/HvRo0atQiehTip4nssupzSJRWPqLnn4HKKikYl1SUWlSxEfzIONOV+sEkUhPwLoiQUVh4BE1QS7kuiIKN8qBgDQaV/BD6A3fqnn37qgf9Z74Wn2R2+nzMnJS8/n8rWYEpPS/OOGTt22yGHHLIMH11YhLcd1yATbr59UM5yKCdPqOoqhm7IqRgG6ACeWoXof5ADTaYg5KVDSTiDEDqzGGWAW2eUSChKDJ5c81iYysC4MVj6JOHjD6nbt29vjSVW6u7du1vgT3oS8D8ksYjLY+RwmHgR0G1Bwapx+lSOmaIIFwx34w3ALT169NjYtWvXrciL+xyzwYZiVEIxqBTcj3C20BlDZw2zrIN/YObgCAVqUl6hvBDtIwf+K2cQbautJKogajoVRZWFswoVhbNKFBoNXTHKwrhMR2Uysw8Uh3HCgTB8UNoFBfED1XigV4kr9yr8OhP4oUh82akCSsS9SF2l4OxAOBVDlQPVME+iz0H4UwAVjXX5/05cSv7ZBoS6dWIfxQGLgaPQTzzYYX816jJ4n5YuqFC9ya44K+0Ehd65vufoToGmEJfbyy0qAJWGSkGEYbZAUJj52wEognagM18/4lhIx1u05usjiF8FRWPeVAI1aWeZdRVD66TKomWsRtzJAJWPdQ/RH88B9hXlYyvQqErhbJoKgNOvSez2EoXCRVAx1a6mLq1oUiE4UtOuoFvhghIwnak/lAAHubxyZPEbXRRuQjfWZmllu512VQIyupZiUKnhZ4j1buxRSfMOmX9+DhwwBVFWQOBUIWhS4J1utasiOE0No8l6K3T0oKnCrqYqi9PUMKcZUJZgymDXmXUJ0Z+PAxzBOPA1CR1wBdFWOBTFqSSsjyqA0wymHJqVmrWWWvCkAtRVGo2jyvG7iqEZh8z/XQ78YQpClnP5AkOVIpgSaHgws26vqfCbrJl9EKhiBMxgM0bdjEPu/10OUPD+FGQrS91Zo65isK7OOqudykAKZjpnEoYbd0gxDL9CP3vhgArYXqIduGBbUVigKkswJWF43bo7lYP23yCkFGRbiBrCgbpC1pC0BySuQ2FYnirL75WtisFXdVVpfi9+KCzEgT1ygEeoTUIQbM4A3IBTSCnYKqy08xVMPtgx5cMeOIVwpOOrodxEk/QESfOh6Qw3kfhjK5SJD7uWra+Zmnjw1oMBLrdIWicm0TCto7MdNbF/jc82aDjDTBpa4M882b5apyx2fKYh1aqfM01NsPndY1tNBjXlKH80PwYFXnO182Uc5uXsh1o8dJavfeJIywHH2U+BvnOkq5uf8pKvCCBagFdaB9ZTee/kpbaDJsF8mZ5xg7XD8NgOD8ZbZ3nI4g8mu6INrkXddHBrY4PmFSQ+GRiUNC5MFabfxKtbXl133QTBwuH3e3Wod9l1ywrmDla+M97v1cUZj/Zgcevr58xL06ipYXDvrS/3yJs91U/z3lt43bo40+3NvsfO3FvCPYWTEdB2jgZ9EWckwKsdbDy1mDMCP23Dz6RBov4AAAufSURBVLTwn1Ivtv3fgpvx2FEdYJwCLIDfV3CnwX4yoEeyzIdPUDci/GOYhhAPzpolFexj4TkB4Gdt1gAfIGwt/LVu7eF3AtAd4NP1b4GPEacccYbCPhyYBjf/DWog7IcBfIpOYvm8aMlP2cxDeB/YD7f9P2E5sLMd/ErJOQD/RFO/Rki+sE7HA4cCzAfvGMs/EWcnwlrCfhpQt61bEP4h/AOEuPyMEOOxrCNgjAFaAfz4wwyEfQHTEMJZlzMAjvq8PUAiDzcjHt+JgWFG6FT4/QXABwJMnfj0lfHOB3hN5x3E4+d1KOxnAYnAi0AycC7APvuS4TDZVvJlMPBvuNfDzTYPAXhhlLKnvJyF8MUIJ69HALwnxzJY5jKEzYPJdvJqyZkAHyRrO3gFKRdx3kV4a9iHAky3FGgLrEbYboTB+BMsuVERMxLAfBXYE52JgFg7kN955fsWbDSZcK3t/5TtPtV21zU+tcPNd2lpJyHSM3Ujwn1HTWit/OtGu9VOP9UOONF2v1I3ou2+yQ5/0hH+H0c5g2z/BQ6/4fDb4oiv1q/svI5RjzrmN3Y4hYZtVB6nwE6BDEbPMy4JgYcGiwA/zZdCxnh8qY1UBlDZ6HcaPUAUeA5e9NO2UQjpPg8gvWy7zYfe4P7a+FrWSNufQhyMLrPDXw4WCL+77HC+sxOM1tnhGQj8K8AvQFL+3gLa2GGGd7Q3hMw6siEJ9hYXWmpGNcQjsz4AegMTgR+B+wCOZhz5OXqTOBJzxFBKtS1LbDPdNt+ESQHk9XiOahx5SX6Ajef9K46iVwPsuHOAdkBH4FmAHXkRDCpeAXADwDqNAzKAlwASR0PSqhpDOKqTqGQ/AyyffJsJkDSc9uNQRj+0hxfo2tIDRDvLZns/A5j+EeBtIBPgTKbCzBGQNAV4F+CISeH9BSAhGzMSsq1Ukn8DHHFnAI8B+OSLHAFMBK5AnJmoC+NovozHfqEA6+wFq5mxaG4FNgEUKtaTdE2NYUb89rCvB861/e6xzU62OZumoz9T4KwCNtAfRDfpZmANEAOwHV8DJOXlFbB/B3CQegC4wDa1b76AexLANkQCmwASy6LcuADOViw3C2Cd/DT/dIROOhogPe6sHNx/Mb6W9U+YfJNPX3f91vYfw/iwP2u7TafAzldfydQAwa2zz5123GkwKVgBgpuv/3KqJQ0JBDgs8OdrwjuAAqA5g2AuB0gUcLrZKQGCex7Apch3AOkfDIR5i3FZ1m22+wPbbWaqQAYOC8IftuNcaqfhzFq3rVRO5n+pHZdKV4vg/6gd9ioDYL/Jdt9YK2JNGNdWFChDsM+043I2GWnbuRwmXcJIMEuB1YDWRWeGq+HXDegPjAG4ZOWMqf2zAXYqNxWN+QR4CTvrobw2igT3OIBkZmGYVHrSfXb6SNhN3rabb7Ma0P2nJlTUCCjMuwHS9awwTI6KNO+g5x6IjO1qx/vEjkPGKu2CRZcAZIgRIpjDAI3HPN4HDrbzUUX91HbrX53xVVrtwEzYuZRYYcehUu0ElDTvz+1wKhTDqVQjgUqgGmgOqJDyX6HCgRIb2vkRcLNsUw87v//ATdJyaM8BzAwAM6AssCtfJthpo+BnBA7mmQDpLTvspRqnxe/rbgJoLgA4m7MvnDx8DW7SKOBjIB84BiA9AKj9OkfaOSY0+M8cO14agnMdUbSNH9jhrRBGPpL4x0IceDTOhXYcHSzVn3Fp5z7QtINmY5IZARozQ0deXtueaZucmkmcBkkdagz5J0yuIdn5nNavBPKAHQDpoBpDFsKsBKhgK4EcgMQ1B4Wam1Z21CD4cQTm9ExQQZiHUSiYOt2z7TwK5eivoxAFkaOpxqGbAl0KcOq2AM4sswESlwTMdwXymYl8psDOmY6DQTuAxLy4bGTb1gCFiGdGbJYNNzvWuGHVNItgrwDY1tVANkBi+Rpf426nH8iE1Vilp22yPJIZsWGWAT6A5e0E+LoxiWndxlZTHq3nA0cDDwNfAqShwDCgGmBbSWxXBsAlzJMAw9jHnHFPBjYCJPZBElAELAdIiYBRIJjkZRrAcCpuDyALuAR8mg6TpG1eCjv7hEtFysE24L+HHB3OzqTgkPqyBTCpCDS/BUjaefRrYXx+nVLpLgaUyUwaIPgbwVIzEAAL/DiKbwVIzOd4Y7OsuXXiJagb4TryPkM/uMfaad7QOE4TYUPt8M/s+Afb7jyYHHm52U0BOHpyZiG6aR6wc9RXfnC24shOofgNwb/uUkhHba7XA4R4HQGWTTKKAnMdwNktsLSBXRXCpIXbDJYwTwKUuJTKZASYy9UT5vNaIOwZQGDWdfifbce/z06v/A+k1bh2uPL6daTjzMwZl/ygErF8zrhc6nFAo2LUIvgZWajl2QgOw5RGyKduFqws6myWWRmwlwO7AG6WOCWygW0AjmjsOHibI7gBcJM2md+azWUc7EWIcztM5svRnqNM4G8AkJajFwt8DEYX4GmACslRaznCObX/BDvTDYb9LZiTga7APXDz+JLrc1XWTbCT1N0BcRgeZYN/Yvkm7DqimZEafnMR7xP4TwBIa4Ey+FPQvoJ9HPAG7BNhciS/C+A3gEfBpKK2ACgUd8NkONvKUf5l5MGBgkqix7sfwp8j+kT4kUecYTnqco9DoeL/sXOpwtmLsxxn5K0A+4CzU12ybA8ORpypI4EpiKuD00q4qXCcHV4DlJg3+2UTPVAe3wZl/gPpBml65SX3KMpLysHPiD8FZgZA2gE32/oR7GcANwF3AM0BzjCs2x0Ip+yQP+TTK0jDZTeMP8FRLir0u4SK6qjYBnYSR3Ljx4SwtwNImwAPQAbT/3KA9Ijt3tMRLwWeHcg0OvJR8OsS17TaUYzL/YCOrs64VCyGv2d7Hm+7n3VGctgpnIz/kO13Ld0kuEc74n1X42v828F/riNMrbNg4R5ljHrUMQvgjrHzDswi8OO+4dU6cenkAHSbo9xBdpzZdh5MRxieO+K57fBkhHEZSOrtCL+rxst6346ne8xzbP8XbH/t+y9s/5G2v+5tbO+A8ZYd/rTtc5ntHm+7OQtzNdDTdgcz2thpAjJGd2NQLSY1RobMAy0wmgyTa8kxQA48KAhO/7Hwz67j3xl+FOi58F+P+Bm2m6MGRzjOFBw1diP8R5iGHPlyBOUozdF4HTAd8bjcYeezcFjNhnc83O2APIAP1VbAZL2HwGgNfG2n6w97B6AcYPkEBWMlwlcjfh/Yudbmg67tMJkHyzoc4GywHv7cDJtRHybTHg30ArwAj7i/gcl0bWEMAqoBjopaFnn0PdwBQlx41YyUsB+GgEMAziKbAdZ9E0xDCE+GZTSgdQmkrYlR+xfxWX/GZyFfaVkwKYTDANZ5E9zaJvJnMLAQ/msc8UfAjzzgQ2GuANi2DKAuLznDs68HIKwjQF7y2RgHwFEA+/JrgPwiX8kbgrLAwZEz7HdIQ/d/D5FRwWpbX3/EY0ftNyEfj2bitKsfTZYF1Kov/Zxx6trrhtdNr/HVH2agHhqmZt281P/3TOaredeNx7KChe8pft306tb4atbXX+OpWTe9+quJ8Fq83lt8TXcgzFpC0dgF2g2lYHA0otYb+h1/Moowlwsd8WoS/vpbKz/1RnyWxTZx9KVp8oEZIMTRMjROIC9Heh/qC2cgbiC9bdH6aV4mvkZy5BPIm2HwZ50MP2Aq77UsDWNUJ9XKwxlAu7MsOH/TZmeZzj6om4/Tbedp9ovq78inFk/hrzyo6699oe3TeJqlmnvkJfI2y2dEVNlhnnXpd/lTN3LIHeJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAY3Hg/wB3cRq/m/+84QAAAABJRU5ErkJggg=="},{"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 orthophoto 2000","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2000/{zoom}/{x}/{y}.jpg","endDate":"2000-01-01T00:00:00.000Z","startDate":"2000-01-01T00:00:00.000Z","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 orthophoto 2005","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2005/{zoom}/{x}/{y}.jpg","endDate":"2005-01-01T00:00:00.000Z","startDate":"2005-01-01T00:00:00.000Z","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","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","description":"French address registry or Base Adresses Nationale"},{"id":"FR-Cadastre","name":"FR-Cadastre","type":"tms","template":"http://tms.cadastre.openstreetmap.fr/*/tout/{zoom}/{x}/{y}.png","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","description":"French land registry","icon":"https://svn.openstreetmap.org/applications/editors/josm/plugins/cadastre-fr/images/cadastre_small.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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,"icon":"http://i.imgur.com/aFlvMpM.png"},{"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","scaleExtent":[0,19],"polygon":[[[-48.2444,-16.0508],[-48.2444,-15.5005],[-47.5695,-15.5005],[-47.5695,-16.0508],[-48.2444,-16.0508]]],"description":"Addresses data from IBGE","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-S2A_R119_N09_20160327T050917","name":"imagico.de OSM images for mapping: Adams Bridge","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R119_N09_20160327T050917&z={zoom}&x={x}&y={-y}","endDate":"2016-03-27T00:00:00.000Z","startDate":"2016-03-27T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[79.01779174804685,8.827572266651268],[79.01401519775389,9.64678471986339],[80.17642021179198,9.650423231331946],[80.17727851867674,8.831304063493132],[79.01779174804685,8.827572266651268]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Supplementing incomplete coverage in other sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2014-07-31T00:00:00.000Z","startDate":"2014-07-31T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[-152.70872943147867,62.30357443926811],[-152.70838610872474,62.58153176976553],[-152.00835101350992,63.54645538851267],[-148.99432055696695,63.53329945446586],[-148.99432055696695,62.30357443926811],[-152.70872943147867,62.30357443926811]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent summer image of the Alaska Range for mapping natural features (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-aral2","name":"imagico.de OSM images for mapping: Aral Sea (high water level)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=aral2&z={zoom}&x={x}&y={-y}","endDate":"2016-03-03T00:00:00.000Z","startDate":"2016-03-03T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[58.049,43.2623],[58.049,46.7189],[58.1014,46.8645],[61.5524,46.8629],[61.5524,46.3896],[61.4675,45.3416],[60.6317,43.2623],[58.049,43.2623]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Water and wetland extents, dams etc. - some remaining winter ice in the north (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-aral1","name":"imagico.de OSM images for mapping: Aral Sea (low water level)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=aral1&z={zoom}&x={x}&y={-y}","endDate":"2016-09-09T00:00:00.000Z","startDate":"2016-09-09T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[58.049,43.2623],[58.049,46.7334],[58.096,46.8645],[61.5524,46.8629],[61.5524,46.3896],[61.4685,45.3544],[60.6267,43.2623],[58.049,43.2623]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Water and wetland extents, dams etc. (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R067_S40_20170417T140051","name":"imagico.de OSM images for mapping: Bahía Blanca (high tide)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R067_S40_20170417T140051&z={zoom}&x={x}&y={-y}","endDate":"2017-04-17T00:00:00.000Z","startDate":"2017-04-17T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-62.9988,-40.7327],[-62.9988,-37.9476],[-61.7505,-37.9474],[-61.7501,-40.7322],[-62.9988,-40.7327]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Tidal flats and islands at the coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R067_S40_20170127T140051","name":"imagico.de OSM images for mapping: Bahía Blanca (low tide)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R067_S40_20170127T140051&z={zoom}&x={x}&y={-y}","endDate":"2017-01-27T00:00:00.000Z","startDate":"2017-01-27T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-62.9988,-40.7327],[-62.9988,-37.9476],[-61.7505,-37.9474],[-61.7501,-40.7322],[-62.9988,-40.7327]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Tidal flats and islands at the coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2014-03-16T00:00:00.000Z","startDate":"2014-03-16T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[114.35999506049737,2.028456548619032],[113.5344754987298,2.030000532161949],[113.53619211249934,3.070767124420059],[114.76511591010677,3.067510236472651],[114.76254098945248,2.088156161702156],[114.35999506049737,2.028456548619032]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing in older pre-2011 images (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-01-01T00:00:00.000Z","startDate":"2014-01-01T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[104.00154570197358,-0.000078769115171],[104.00137404059662,1.45099139170518],[104.91014937018647,1.451162998032411],[104.91014937018647,-0.000078769115171],[104.00154570197358,-0.000078769115171]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing Islands in OSM (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80770232017156LGN00","name":"imagico.de OSM images for mapping: Bogoslof Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80770232017156LGN00&z={zoom}&x={x}&y={-y}","endDate":"2017-06-05T00:00:00.000Z","startDate":"2017-06-05T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-168.2544,53.8749],[-168.2544,54.0213],[-167.8591,54.0213],[-167.8591,53.8749],[-168.2544,53.8749]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent image from after the eruption (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-10-18T00:00:00.000Z","startDate":"2013-10-18T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[3.246529403113632,-54.47046993167111],[3.246529403113632,-54.375391687979096],[3.463852706336288,-54.375391687979096],[3.463852706336288,-54.47046993167111],[3.246529403113632,-54.47046993167111]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","best":true,"description":"For more accurate coastline and glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R065_N47_20160929T102022","name":"imagico.de OSM images for mapping: Cental Alps in late September 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R065_N47_20160929T102022&z={zoom}&x={x}&y={-y}","endDate":"2016-09-29T00:00:00.000Z","startDate":"2016-09-29T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[10.559062957763668,45.95484945195885],[7.473964691162107,45.95532682303484],[7.555847167968747,46.27080015119853],[8.05469512939453,47.66469371011084],[11.752452850341793,47.664809318453564],[11.752452850341793,46.813336457338615],[11.38423919677734,45.955088138010865],[10.559062957763668,45.95484945195885]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date image for glacier mapping - beware of some fresh snow at higher altitudes (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-12-10T00:00:00.000Z","startDate":"2015-12-10T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-34.17701089820909,-55.29692751183208],[-35.19599283180284,-55.282851769908206],[-35.16663873634385,-54.7209735214882],[-34.12516916236925,-54.73465315976587],[-34.14010370216417,-55.29692751183208],[-34.17701089820909,-55.29692751183208]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R086_N60_20160831T213532","name":"imagico.de OSM images for mapping: Cook Inlet","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R086_N60_20160831T213532&z={zoom}&x={x}&y={-y}","endDate":"2016-08-31T00:00:00.000Z","startDate":"2016-08-31T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-154.5102,59.4577],[-154.5097,60.6888],[-153.5403,62.1718],[-148.0423,62.1718],[-148.0445,61.5342],[-149.7291,59.4584],[-154.5102,59.4577]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Tidal flats and glaciers in surrounding mountains (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-EO1A0040712016264110KF","name":"imagico.de OSM images for mapping: Coropuna","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A0040712016264110KF&z={zoom}&x={x}&y={-y}","endDate":"2016-09-21T00:00:00.000Z","startDate":"2016-09-21T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-72.7594470977783,-15.68684010813036],[-72.7594470977783,-15.49570157136026],[-72.74434089660643,-15.426295586903299],[-72.41286277770995,-15.426295586903299],[-72.41286277770995,-15.652957427428944],[-72.42410659790038,-15.686674840407827],[-72.7594470977783,-15.68684010813036]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-12-21T00:00:00.000Z","startDate":"2015-12-21T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[1.839749701876779,6.257803795151386],[1.839749701876779,7.114271792431897],[2.549397834200998,7.114271792431897],[2.549397834200998,6.489052510574106],[2.497813590426584,6.258059752887941],[1.839749701876779,6.257803795151386]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Patchy and partly cloudy coverage in usual sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R040_N01_20160311T164128","name":"imagico.de OSM images for mapping: Darwin and Wolf islands, Galapagos","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R040_N01_20160311T164128&z={zoom}&x={x}&y={-y}","endDate":"2016-03-11T00:00:00.000Z","startDate":"2016-03-11T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-92.05216379429558,1.321295617717369],[-92.05216379429558,1.72181118585353],[-91.74849481846549,1.72181118585353],[-91.74849481846549,1.321295617717369],[-92.05216379429558,1.321295617717369]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent image, only old and poor images in other sources currently (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2014-09-02T00:00:00.000Z","startDate":"2014-09-02T00:00:00.000Z","scaleExtent":[0,11],"polygon":[[[-84.34798733886554,74.38945823827667],[-84.34798733886554,75.89030323920836],[-79.14870755370929,75.89030323920836],[-79.14870755370929,74.38945823827667],[-84.34798733886554,74.38945823827667]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Coastline mostly mapped meanwhile (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-08-27T00:00:00.000Z","startDate":"2013-08-27T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[-13.047005598725303,64.2110895294821],[-15.164963667572959,64.22408122727819],[-15.168053572358117,64.81572800422087],[-13.043572371186242,64.80359943673454],[-13.047005598725303,64.2110895294821]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing islets and inaccurate coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2012-02-05T00:00:00.000Z","startDate":"2012-02-05T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-78.531997745432,-1.805085317123331],[-78.531997745432,-1.608105565001241],[-78.33561713019762,-1.608105565001241],[-78.33561713019762,-1.805085317123331],[-78.531997745432,-1.805085317123331]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"2007 ASTER image offering better glacier coverage than common sources (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-01-09T00:00:00.000Z","startDate":"2016-01-09T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-56.13476090727487,-61.63471600102006],[-56.13476090727487,-61.199363166283845],[-55.83263688383738,-60.84015069906498],[-53.72343354521433,-60.83981613078141],[-53.72343354521433,-61.63471600102006],[-56.13476090727487,-61.63471600102006]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Fairly clear up-to-date image for updating glacier edges (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-enderby","name":"imagico.de OSM images for mapping: Enderby Land and Kemp Coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=enderby&z={zoom}&x={x}&y={-y}","endDate":"2017-03-27T00:00:00.000Z","startDate":"2017-01-25T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[45.4547,-68.5091],[45.4547,-67.5724],[49.7155,-65.7176],[59.2693,-65.7176],[67.3735,-67.3449],[67.3735,-68.2581],[67.088,-68.5091],[45.4547,-68.5091]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Sentinel-2 images of Enderby Land and Kemp Coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-12-13T00:00:00.000Z","startDate":"2015-12-13T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-24.758781955967567,14.748140156641956],[-24.758781955967567,15.092493544965103],[-24.267057941685337,15.092493544965103],[-24.267057941685337,14.748140156641956],[-24.758781955967567,14.748140156641956]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Image from after the 2014/2015 eruption (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[-43.9774,59.7171],[-44.545,59.7302],[-44.9203,59.7672],[-45.3587,59.8218],[-45.763,59.8848],[-46.0859,59.9827],[-46.3381,60.119],[-46.577,60.2652],[-46.8114,60.4418],[-47.2635,60.5314],[-47.6937,60.5549],[-48.1457,60.6192],[-48.5771,60.7015],[-48.8689,60.8506],[-49.0578,61.0555],[-49.396,61.2957],[-49.7601,61.4934],[-50.2064,61.7324],[-50.4699,61.9539],[-50.8647,62.1596],[-51.0631,62.3869],[-51.2121,62.6001],[-51.3005,62.8389],[-51.4238,62.9979],[-51.6767,63.1944],[-51.9465,63.4079],[-52.0253,63.6377],[-52.2255,63.8378],[-52.3658,64.0705],[-52.4829,64.3792],[-52.4988,64.6788],[-52.789,64.9063],[-53.2046,65.1321],[-53.6649,65.4753],[-53.9977,65.8019],[-54.1348,66.1568],[-54.1441,66.5235],[-54.2285,66.8319],[-54.4519,67.303],[-54.5141,67.7648],[-54.604,68.2021],[-54.568,68.5698],[-54.598,68.8347],[-54.7606,69.1207],[-55.0028,69.4125],[-55.2735,69.6187],[-55.3808,69.8283],[-55.3945,70.0838],[-55.3094,70.2573],[-55.4307,70.479],[-55.5501,70.6707],[-55.7654,70.861],[-56.2489,71.2343],[-56.5018,71.5429],[-56.5867,71.9015],[-56.5189,72.2355],[-56.5085,72.5258],[-56.8923,72.8144],[-57.4027,73.1054],[-57.8066,73.4566],[-58.1461,73.7696],[-58.3554,74.0972],[-58.5125,74.3783],[-58.7336,74.6328],[-59.3551,74.8869],[-60.1412,75.102],[-61.0067,75.2763],[-61.911,75.3886],[-62.4706,75.5595],[-62.9776,75.7454],[-64.1463,75.779],[-65.4481,75.7235],[-66.7068,75.6792],[-67.8379,75.6525],[-69.0456,75.6195],[-70.055,75.5344],[-71.0898,75.4705],[-72.1119,75.4476],[-74.2311,76.4102],[-74.5601,76.5328],[-74.5601,82.6959],[-14.4462,82.6959],[-14.3994,82.5997],[-13.5339,82.4379],[-12.0312,82.3426],[-10.7796,82.3196],[-10.7796,80.1902],[-11.2123,80.069],[-11.136,79.8103],[-10.7796,79.5176],[-10.7796,79.0441],[-11.2626,78.7128],[-12.2579,78.3558],[-13.2398,78.1272],[-13.7649,77.9279],[-14.1169,77.6779],[-14.7129,77.5278],[-15.5507,77.3655],[-16.0936,77.0771],[-16.0586,76.5548],[-15.838,75.9611],[-15.6879,75.4726],[-16.253,75.058],[-17.0427,74.6425],[-18.3155,74.2702],[-19.4463,73.9378],[-19.8329,73.632],[-20.2938,73.3524],[-20.7831,73.0446],[-21.01,72.6766],[-20.8774,72.2926],[-20.7672,71.8726],[-20.7765,71.4304],[-20.9411,70.9802],[-21.219,70.6126],[-21.5326,70.3001],[-21.8039,70.0911],[-22.166,69.8947],[-22.4831,69.7539],[-22.9027,69.6585],[-23.3545,69.544],[-23.9177,69.4036],[-24.1794,69.3088],[-24.6745,69.1084],[-25.1222,68.9555],[-25.6659,68.7995],[-26.0994,68.583],[-26.6316,68.4043],[-27.7638,68.2813],[-28.4575,68.0023],[-29.353,67.8135],[-30.6456,67.4911],[-31.7673,67.0005],[-32.9783,66.2596],[-33.9313,66.0156],[-34.8956,65.7403],[-35.5914,65.5208],[-36.1483,65.372],[-36.7532,65.2559],[-37.1858,65.1349],[-37.6032,64.9727],[-38.0624,64.4901],[-38.5304,64.1244],[-39.0545,63.7213],[-39.3131,63.4405],[-39.5739,62.7506],[-39.9532,62.2739],[-40.2757,61.8547],[-40.714,61.3365],[-41.2091,60.8495],[-41.821,60.5526],[-42.4368,60.3264],[-42.8643,60.0299],[-43.1131,59.9147],[-43.3282,59.83],[-43.5459,59.7695],[-43.797,59.7284],[-43.9774,59.7171]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Landsat mosaic of Greenland (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-04-12T00:00:00.000Z","startDate":"2016-04-12T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[73.06896521028185,-53.270590689700434],[73.06896521028185,-52.875489636268725],[73.67338491853381,-52.87673289134188],[74.08863378938341,-52.94950473139763],[74.08863378938341,-53.270590689700434],[73.06896521028185,-53.270590689700434]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent image of Heard island with interior mostly cloud covered but mostly well visible coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-09-16T00:00:00.000Z","startDate":"2013-09-16T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[-69.85679747431641,-55.55949231551995],[-72.26520659296875,-55.149427383391455],[-72.26520659296875,-54.51089432315929],[-72.08530546992188,-54.17909103768387],[-69.49115874140625,-54.17889010631196],[-69.49150206416016,-55.28378528847367],[-69.62230803339844,-55.55910398108892],[-69.85679747431641,-55.55949231551995]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"A lot of very coarse coastlines could be improved here, much snow cover though so no use for glacier mapping (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_kangerlussuaq_20151008","name":"imagico.de OSM images for mapping: Kangerlussuaq Autumn","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_kangerlussuaq_20151008&z={zoom}&x={x}&y={-y}","endDate":"2015-10-08T00:00:00.000Z","startDate":"2015-10-08T00:00:00.000Z","scaleExtent":[0,17],"polygon":[[[-50.6992,66.9888],[-50.721,67.0017],[-50.7341,67.0125],[-50.7396,67.0193],[-50.7396,67.0212],[-50.7158,67.0265],[-50.7017,67.0265],[-50.6829,67.0176],[-50.6686,67.0077],[-50.6638,66.998],[-50.6642,66.9946],[-50.6891,66.9888],[-50.6992,66.9888]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS image of the airport and settlement - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_kangerlussuaq_20160518","name":"imagico.de OSM images for mapping: Kangerlussuaq Spring","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_kangerlussuaq_20160518&z={zoom}&x={x}&y={-y}","endDate":"2016-05-18T00:00:00.000Z","startDate":"2016-05-18T00:00:00.000Z","scaleExtent":[0,18],"polygon":[[[-50.7519,66.9996],[-50.7555,67.0023],[-50.7555,67.0033],[-50.6395,67.0297],[-50.6162,67.0339],[-50.6097,67.0281],[-50.6331,67.022],[-50.7323,66.9996],[-50.7519,66.9996]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS image of the airport and roads - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R021_N44_20160807T083013","name":"imagico.de OSM images for mapping: Kerch Strait","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R021_N44_20160807T083013&z={zoom}&x={x}&y={-y}","endDate":"2016-08-07T00:00:00.000Z","startDate":"2016-08-07T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[35.932588577270494,44.96236872935039],[35.932588577270494,45.559256426515695],[37.369909286499016,45.559256426515695],[37.369909286499016,44.96236872935039],[35.932588577270494,44.96236872935039]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"State of bridge construction in August 2016 (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ls_polar2","name":"imagico.de OSM images for mapping: Landsat off-nadir July 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ls_polar2&z={zoom}&x={x}&y={-y}","endDate":"2016-07-17T00:00:00.000Z","startDate":"2016-07-17T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[-79.05174500251786,81.91484289044183],[-79.05174500251786,83.43338556749623],[-73.60389956385866,83.80224987787145],[-26.424486898081835,83.80224987787145],[-21.492998879371186,83.50352415480617],[-16.888354121159868,83.15094632775453],[-16.888354121159868,81.91484289044183],[-79.05174500251786,81.91484289044183]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Latest images north of the regular Landsat limit (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-11-16T00:00:00.000Z","startDate":"2013-11-16T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-28.210747081406492,-56.72108048139938],[-28.210747081406492,-56.624975043089115],[-27.96956284678735,-56.624975043089115],[-27.96956284678735,-56.72108048139938],[-28.210747081406492,-56.72108048139938]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing in other image sources (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-10-13T00:00:00.000Z","startDate":"2015-10-13T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-27.992928409215843,-56.73479060902333],[-28.227761172887714,-56.732624892496354],[-28.2241562839717,-56.600752537318456],[-27.969754123327167,-56.60283135691063],[-27.97318735086623,-56.73479060902333],[-27.992928409215843,-56.73479060902333]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-05-17T00:00:00.000Z","startDate":"2013-05-17T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[-85.76109385682587,81.39333391115835],[-89.83015512094161,82.14951616258433],[-89.83152841195212,82.24404688557661],[-84.99342418195555,82.73098798225534],[-79.95207288240479,83.13107965605444],[-74.55641250214465,83.46266728201661],[-69.35850602739671,83.70450775086888],[-28.207840897721187,83.70450775086888],[-23.06623935440381,83.46532469372944],[-17.96583654140148,83.15518123848051],[-17.96720983241198,82.72386035102944],[-22.781968115230015,81.44190408358111],[-85.76109385682587,81.39333391115835]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"First available image north of the regular Landsat limit, mostly with seasonal snow cover so difficult to interpret (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R092_S02_20160613T075613","name":"imagico.de OSM images for mapping: Mount Kenya 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S02_20160613T075613&z={zoom}&x={x}&y={-y}","endDate":"2016-06-13T00:00:00.000Z","startDate":"2016-06-13T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[37.20665931701659,-0.266846645776291],[37.20665931701659,-0.011930465612033],[37.5655174255371,-0.011930465612033],[37.5655174255371,-0.266846645776291],[37.20665931701659,-0.266846645776291]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R092_S05_20160802T075556","name":"imagico.de OSM images for mapping: Mount Kilimanjaro 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S05_20160802T075556&z={zoom}&x={x}&y={-y}","endDate":"2016-08-02T00:00:00.000Z","startDate":"2016-08-02T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[37.24768638610839,-3.229213650135676],[37.24768638610839,-2.968155849006605],[37.61581420898436,-2.968155849006605],[37.61581420898436,-3.229213650135676],[37.24768638610839,-3.229213650135676]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-06-08T00:00:00.000Z","startDate":"2015-06-08T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[150.38853376619625,-2.800534349432724],[150.38853376619625,-2.383396178206425],[150.83348005525875,-2.383396178206425],[150.83348005525875,-2.800534349432724],[150.38853376619625,-2.800534349432724]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Many missing islands in OSM (mostly mapped meanwhile) (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-northsea_s2_2016","name":"imagico.de OSM images for mapping: North Sea Coast 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=northsea_s2_2016&z={zoom}&x={x}&y={-y}","endDate":"2016-09-25T00:00:00.000Z","startDate":"2016-09-25T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[5.1562,52.8755],[5.1615,53.0325],[6.4155,55.7379],[9.8813,55.7459],[9.8813,53.2428],[9.6846,52.8877],[5.1562,52.8755]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-northsea_s2_2017","name":"imagico.de OSM images for mapping: North Sea Coast 2017","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=northsea_s2_2017&z={zoom}&x={x}&y={-y}","endDate":"2017-06-02T00:00:00.000Z","startDate":"2017-06-02T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[5.1713,53.0918],[6.477,55.8973],[9.8813,55.8973],[9.8813,53.2761],[9.7789,53.0918],[5.1713,53.0918]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ural_s2_2016","name":"imagico.de OSM images for mapping: Northern and Polar Ural mountains August 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ural_s2_2016&z={zoom}&x={x}&y={-y}","endDate":"2016-08-12T00:00:00.000Z","startDate":"2016-08-12T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[59.198977223476454,64.8920468958533],[59.198977223476454,66.91656046303187],[60.733286610683486,68.44289182710118],[67.7329509173241,68.44327026354412],[67.7329509173241,67.748828729217],[64.21646761043934,64.9195663902952],[59.198977223476454,64.8920468958533]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date late summer imagery with few clouds - caution: not all visible snow is glaciers (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ndvina","name":"imagico.de OSM images for mapping: Northern Dvina delta at low tide","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ndvina&z={zoom}&x={x}&y={-y}","endDate":"2015-09-13T00:00:00.000Z","startDate":"2015-09-13T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[37.7291,64.1971],[37.7291,65.1161],[37.8592,65.2705],[41.3223,65.2705],[41.3223,64.3142],[41.2114,64.1973],[37.7291,64.1971]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Beaches, tidal flats and other costal forms (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2012-07-09T00:00:00.000Z","startDate":"2012-07-09T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[-81.62923243782096,82.45969864814401],[-83.03136255954291,82.47985512217643],[-83.03136255954291,83.05876272004272],[-72.80309111332822,83.09567468670448],[-65.65785798568925,83.03232446260982],[-65.8116665788654,82.45969864814401],[-81.62923243782096,82.45969864814401]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Assembled from July 2012 ASTER imagery (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-nellesmere_ast_2016","name":"imagico.de OSM images for mapping: Northern Ellesmere Island July 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast_2016&z={zoom}&x={x}&y={-y}","endDate":"2012-07-15T00:00:00.000Z","startDate":"2012-07-08T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[-78.89729497133754,82.17577067162792],[-82.64500613899595,82.19425721404356],[-82.64500613899595,83.08067098163464],[-66.58986093522367,83.08497116318647],[-63.78010752773773,82.98907949583335],[-63.78010752773773,82.72198178031782],[-65.0092029821365,82.17577067162792],[-78.89729497133754,82.17577067162792]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Assembled from July 2016 ASTER imagery (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-08-21T00:00:00.000Z","startDate":"2015-08-21T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[7.63567991501593,53.28027339774928],[7.63567991501593,53.66770140276793],[8.49433012253546,55.502457780526],[9.207754805152648,55.48106268908912],[9.207754805152648,53.28027339774928],[7.63567991501593,53.28027339774928]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-08-21T00:00:00.000Z","startDate":"2015-08-21T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[7.63567991501593,53.28027339774928],[7.63567991501593,53.66810821588294],[8.49433012253546,55.502457780526],[9.207754805152648,55.48106268908912],[9.207754805152648,53.28027339774928],[7.63567991501593,53.28027339774928]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2012-08-13T00:00:00.000Z","startDate":"2005-06-21T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[-52.49221819430999,82.48971755550389],[-52.49221819430999,82.94294978186194],[-49.28695697579964,83.47311821807558],[-44.52850362441216,83.7321400994933],[-29.525299334683975,83.7321400994933],[-25.263977329098022,83.58271128961059],[-21.183929736898254,83.39775984253468],[-21.183929736898254,82.74312310369845],[-23.404541300879075,82.48971755550389],[-52.49221819430999,82.48971755550389]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Assembled from mostly 2012 ASTER imagery, some 2005 images mainly in the northeast (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-03-13T00:00:00.000Z","startDate":"2013-03-13T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[73.22790413350113,-53.20333324999222],[73.22790413350113,-53.01072925838941],[73.2594898268605,-52.94943913810479],[73.78992348164566,-52.94943913810479],[73.78992348164566,-53.06048282358537],[73.71782570332533,-53.20333324999222],[73.22790413350113,-53.20333324999222]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Glaciers of Northwest Heard Island (mapped meanwhile) (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-06-07T00:00:00.000Z","startDate":"2016-06-07T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-80.01653561766223,8.848981570244637],[-80.01653561766223,9.41480707574399],[-79.46859250242785,9.41480707574399],[-79.46859250242785,8.848981570244637],[-80.01653561766223,8.848981570244637]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Images of the new locks (but partly cloudy) (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-EO1A0120532016364110KF","name":"imagico.de OSM images for mapping: Panama Canal - Pacific side","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A0120532016364110KF&z={zoom}&x={x}&y={-y}","endDate":"2016-12-30T00:00:00.000Z","startDate":"2016-12-30T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-79.62538719177245,8.770827350748924],[-79.68684196472167,8.821974500616129],[-79.6866703033447,8.93705081902936],[-79.65362548828124,9.0929436313527],[-79.268159866333,9.0929436313527],[-79.32832717895505,8.770827350748924],[-79.62538719177245,8.770827350748924]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"New locks with less clouds than in the Sentinel-2 image - make sure to check image alignment (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R078_N68_20160930T081002","name":"imagico.de OSM images for mapping: Pechora Sea Coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N68_20160930T081002&z={zoom}&x={x}&y={-y}","endDate":"2016-09-30T00:00:00.000Z","startDate":"2016-09-30T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[53.1802,67.5344],[53.1821,68.414],[54.2107,69.3367],[55.3584,70.2786],[59.004,70.2786],[60.6947,69.977],[61.9837,69.7161],[61.9823,68.9395],[59.9153,67.5344],[53.1802,67.5344]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Sentinel-2 image of the Pechora Sea coast in autumn 2016 (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-02-02T00:00:00.000Z","startDate":"2016-02-02T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[-53.20921946177197,-84.12524693598144],[-60.615377881406225,-83.78609327915953],[-60.615377881406225,-82.29968785439104],[-48.72405102147429,-82.29987186164387],[-44.52178052933989,-82.43683433550413],[-44.51354078327688,-84.12524693598144],[-53.20921946177197,-84.12524693598144]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-08-31T00:00:00.000Z","startDate":"2015-08-31T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[19.112325688609005,42.1531576323006],[19.08425905347717,43.08073531915633],[20.63298799634826,43.09602978090892],[20.637880345591427,42.167791043253985],[19.112325688609005,42.1531576323006]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Late summer imagery where usual sources are severely limited by clouds and snow (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2011-04-15T00:00:00.000Z","startDate":"2011-04-15T00:00:00.000Z","scaleExtent":[0,15],"polygon":[[[-51.238571767352376,68.79971882076842],[-51.243335370562825,68.85302612951142],[-51.151668195269856,68.85302612951142],[-51.14038145973519,68.80116208175376],[-51.238571767352376,68.79971882076842]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS image of the settlement - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-01-01T00:00:00.000Z","startDate":"2015-01-01T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[67.96839858817646,22.36264542957619],[67.86231185721942,22.38391650007107],[67.86231185721942,24.886930816927297],[71.48986007499286,24.886930816927297],[71.48986007499286,22.36264542957619],[67.96839858817646,22.36264542957619]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Land/water distinction difficult to properly map based on Bing/Mapbox images (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-08-28T00:00:00.000Z","startDate":"2015-08-28T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[23.808114560320394,41.584878805945024],[22.992379697039144,41.6019534981177],[23.011863263323328,42.29983747360261],[23.99402383156063,42.283393175568236],[23.965613873674886,41.584878805945024],[23.808114560320394,41.584878805945024]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Late summer imagery where usual sources are severely limited by clouds and snow (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-02-09T00:00:00.000Z","startDate":"2015-02-09T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[29.766296776846374,0.206886934953159],[29.766296776846374,0.509176367154027],[30.034603509024116,0.509176367154027],[30.034603509024116,0.206886934953159],[29.766296776846374,0.206886934953159]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent image of most of the remaining Rwenzori Mountains glaciers (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R078_N01_20160702T082522","name":"imagico.de OSM images for mapping: Rwenzori Mountains 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N01_20160702T082522&z={zoom}&x={x}&y={-y}","endDate":"2016-07-02T00:00:00.000Z","startDate":"2016-07-02T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[29.8051357269287,0.235862065771959],[29.8051357269287,0.467085433008179],[30.02503395080565,0.467085433008179],[30.02503395080565,0.235862065771959],[29.8051357269287,0.235862065771959]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2014-02-05T00:00:00.000Z","startDate":"2014-02-05T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-180,-67.4263452007858],[-180,-67.32544337276457],[-179.8247337341308,-67.3253771978419],[-179.8247337341308,-67.4263452007858],[-180,-67.4263452007858]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2015-12-13T00:00:00.000Z","startDate":"2015-12-13T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-42.12874872458635,-53.72050213468143],[-42.14625818503558,-53.45782244664258],[-41.67573435080706,-53.445862233424414],[-41.6558216310805,-53.70871763480476],[-42.12874872458635,-53.72050213468143]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-09-27T00:00:00.000Z","startDate":"2013-09-27T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[120.84382442048364,-3.595452324350203],[120.84382442048364,-3.159848173206955],[120.98184016755395,-2.514681686347053],[122.62618449738794,-2.514681686347053],[122.62618449738794,-3.002148034113534],[122.5007000308352,-3.595452324350203],[120.84382442048364,-3.595452324350203]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Missing islands and coarse coastline due to cloud cover in Bing, lakes could also use additional detail (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-02-04T00:00:00.000Z","startDate":"2016-02-04T00:00:00.000Z","scaleExtent":[0,10],"polygon":[[[156.96951345925345,-84.50097988272655],[154.50857596843485,-84.46255082580927],[154.50857596843485,-82.60681485793681],[175.46774337070775,-82.58504749645738],[177.00582930246938,-83.52806548607914],[177.00582930246938,-84.19262083779002],[171.93838547371908,-84.34632646581997],[166.83798266071676,-84.44370142483508],[161.67028858819987,-84.50045345467909],[156.96951345925345,-84.50097988272655]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81030632015286LGN00","name":"imagico.de OSM images for mapping: Sudirman Range 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81030632015286LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-10-13T00:00:00.000Z","startDate":"2015-10-13T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[136.4226,-4.2853],[136.4226,-3.6447],[137.7971,-3.6447],[137.7971,-4.2853],[136.4226,-4.2853]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Older image of the Sudirman Range with no fresh snow showing glacier extent (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R088_S05_20160812T011732","name":"imagico.de OSM images for mapping: Sudirman Range 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R088_S05_20160812T011732&z={zoom}&x={x}&y={-y}","endDate":"2016-08-12T00:00:00.000Z","startDate":"2016-08-12T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[136.8044,-4.2585],[136.8044,-3.7836],[137.7701,-3.7836],[137.7701,-4.2585],[136.8044,-4.2585]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Cloud free image of the Sudirman Range but with fresh snow (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-s2sval","name":"imagico.de OSM images for mapping: Svalbard mosaic","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=s2sval&z={zoom}&x={x}&y={-y}","endDate":"2016-01-01T00:00:00.000Z","startDate":"2016-01-01T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[16.6108,76.4137],[16.4731,76.4268],[16.3788,76.4589],[14.4124,77.1324],[14.0784,77.2536],[10.9875,78.4054],[10.631,78.5605],[10.2314,78.8392],[10.3952,79.6074],[10.516,79.7731],[10.9632,79.8707],[20.2294,80.849],[20.4702,80.8493],[25.1752,80.6817],[33.4391,80.3438],[33.7809,80.3016],[34.0395,80.239],[33.977,80.1527],[25.5722,76.5917],[25.2739,76.481],[25.1416,76.4327],[24.937,76.4176],[16.6108,76.4137]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Sentinel-2 mosaic of Svalbard (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2011-05-07T00:00:00.000Z","startDate":"2011-05-07T00:00:00.000Z","scaleExtent":[0,15],"polygon":[[[-68.93976917529807,76.51132557714853],[-68.93976917529807,76.54990046497333],[-68.76634826923117,76.55175699880375],[-68.50992908740743,76.55175699880375],[-68.50743999744161,76.51611959755911],[-68.67897262836203,76.51193618208278],[-68.93976917529807,76.51132557714853]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS image - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_thule2_2015.09.25","name":"imagico.de OSM images for mapping: Thule Airbase DMS low altitude overflight September 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_thule2_2015.09.25&z={zoom}&x={x}&y={-y}","endDate":"2015-09-25T00:00:00.000Z","startDate":"2015-09-25T00:00:00.000Z","scaleExtent":[0,17],"polygon":[[[-68.74291885235837,76.52635852412212],[-68.74446380475094,76.52840070669755],[-68.74806869366695,76.54938731810256],[-68.7461482320123,76.56016657973251],[-68.72275936940244,76.56022393334496],[-68.72017371991207,76.5577475347327],[-68.71853220799495,76.5292079974043],[-68.71977675297786,76.52636602351234],[-68.74291885235837,76.52635852412212]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS aerial images from Thule Airbase - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_thule_2015.10.06","name":"imagico.de OSM images for mapping: Thule Airbase DMS overflight October 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_thule_2015.10.06&z={zoom}&x={x}&y={-y}","endDate":"2015-10-06T00:00:00.000Z","startDate":"2015-10-06T00:00:00.000Z","scaleExtent":[0,16],"polygon":[[[-68.81923965911197,76.52510098413808],[-68.82651380996036,76.54176603738404],[-68.77344898680974,76.5439032956252],[-68.7021022270136,76.54544610909097],[-68.59176687697696,76.54560088014632],[-68.59183124999333,76.52793072237704],[-68.65970186690618,76.52510098413808],[-68.81923965911197,76.52510098413808]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS aerial images from Thule Airbase - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_thule_2015.09.25","name":"imagico.de OSM images for mapping: Thule Airbase DMS overflight September 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_thule_2015.09.25&z={zoom}&x={x}&y={-y}","endDate":"2015-09-25T00:00:00.000Z","startDate":"2015-09-25T00:00:00.000Z","scaleExtent":[0,16],"polygon":[[[-68.7777130980429,76.50687742381471],[-68.77661875676482,76.57064446843503],[-68.68115357350676,76.57065443536027],[-68.67630413960784,76.55384487076157],[-68.67619685124725,76.5307435998188],[-68.6852305312094,76.50688243050337],[-68.7777130980429,76.50687742381471]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS aerial images from Thule Airbase - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R094_N79_20160812T105622","name":"imagico.de OSM images for mapping: Ushakov Island August 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R094_N79_20160812T105622&z={zoom}&x={x}&y={-y}","endDate":"2016-08-12T00:00:00.000Z","startDate":"2016-08-12T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[78.45885691499899,80.72643412860921],[78.45885691499899,80.9098976404357],[80.48892435884663,80.9098976404357],[80.48892435884663,80.72643412860921],[78.45885691499899,80.72643412860921]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date late summer imagery with few clouds (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2014-12-24T00:00:00.000Z","startDate":"2014-12-24T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[153.0613810625655,-11.789228234021259],[153.0613810625655,-11.288690822294749],[153.10927458673538,-11.072292520575749],[154.41201277643268,-11.072292520575749],[154.41201277643268,-11.789228234021259],[153.0613810625655,-11.789228234021259]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Coarse coastline due to cloud cover in Bing/Mapbox (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-01-31T00:00:00.000Z","startDate":"2016-01-31T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-72.8669610523419,-41.51741123877955],[-72.8669610523419,-41.045274923011036],[-72.23181395761533,-41.045274923011036],[-71.87510161630674,-41.10829439141359],[-72.00007109872861,-41.51741123877955],[-72.8669610523419,-41.51741123877955]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Image from after the 2015 eruption (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R089_N52_20160623T024048","name":"imagico.de OSM images for mapping: Vostochny Cosmodrome","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R089_N52_20160623T024048&z={zoom}&x={x}&y={-y}","endDate":"2016-06-23T00:00:00.000Z","startDate":"2016-06-23T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[126.36143429881301,51.375528375017275],[126.34804471141064,52.33932231282816],[128.60762341624462,52.340895519845674],[128.6117432892915,51.375528375017275],[126.36143429881301,51.375528375017275]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent image showing newest features (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2013-10-09T00:00:00.000Z","startDate":"2013-10-09T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[75.98364343730569,34.97850982318471],[73.96164407817483,35.36957188964085],[74.44281091777444,37.09391400468158],[76.50600900737405,36.7026732100855],[75.98364343730569,34.97850982318471]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Represents approximately minimum snow cover so can be well used for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"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}","endDate":"2016-05-10T00:00:00.000Z","startDate":"2016-05-10T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-71.18070648306262,-14.4978507264954],[-71.17976234548938,-13.710292880050797],[-70.5563740550841,-13.71262765059222],[-70.5563740550841,-14.4978507264954],[-71.18070648306262,-14.4978507264954]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Poor and outdated imagery in other sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"IPR-orotofoto-last-tms","name":"IPR ortofoto LAST (tmsproxy)","type":"tms","template":"http://osm-{switch:a,b,c}.zby.cz/tiles_ipr_last.php/{zoom}/{x}/{y}.jpg","scaleExtent":[1,18],"polygon":[[[14.81231552124,49.93089301941],[14.18754582291,49.87687266984],[14.12025456314,50.19881542327],[14.74502426147,50.25247461226],[14.81231552124,49.93089301941]]]},{"id":"IPR-orotofoto-vege-tms","name":"IPR ortofoto Low-Vegetation (tmsproxy)","type":"tms","template":"http://osm-{switch:a,b,c}.zby.cz/tiles_ipr_vege.php/{zoom}/{x}/{y}.jpg","scaleExtent":[1,20],"polygon":[[[14.30454236984,49.99538124382],[14.3160436821,49.94205148763],[14.3499983888,49.94508261663],[14.35383872175,49.92726356386],[14.42385321818,49.93351545169],[14.4200902288,49.95097343212],[14.48865449494,49.95709281879],[14.48479036398,49.9750111737],[14.55385989188,49.98117257481],[14.55011770159,49.99851689993],[14.58455395868,50.0015874108],[14.58829614897,49.98424419323],[14.69168128485,49.99346468175],[14.67633637226,50.06452744171],[14.71278864961,50.06777324036],[14.70115373952,50.12158114828],[14.66470146217,50.11833899243],[14.6610031918,50.13543086714],[14.62755290441,50.13245658485],[14.61965341283,50.16894659259],[14.58542741996,50.16590546732],[14.58162921725,50.18344165464],[14.40776267983,50.167995553],[14.41156088254,50.15045369625],[14.37764851321,50.14743927281],[14.37379555571,50.16523508727],[14.33892816423,50.16213672855],[14.34278112173,50.14433976066],[14.27367931007,50.13819641038],[14.27749028245,50.12058459573],[14.20879964298,50.11447476994],[14.21288816219,50.09557069695],[14.24656290855,50.09856724424],[14.25417384067,50.06335893014],[14.21987061144,50.0603042129],[14.22369648177,50.04259477081],[14.257999711,50.04565061557],[14.26952647673,49.99225864496],[14.30454236984,49.99538124382]]]},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAB3RJTUUH3gQOFR0YB1KT3QAAAAlwSFlzAAAewQAAHsEBw2lUUwAAAARnQU1BAACxjwv8YQUAAAS/SURBVHjandN7TFNXHAfwzrn/lm3ZHy7LYrJkybK5zMw9fCEoPjbeChoHTtBVRF7l1ZZSaG8flCtvsFVpoZZHC5Y6jDM+UScDaxF5lIfSAaMIlVKBS8EZN4d+d9voZpbMFX/JN7nnnvM7n5xzcxmM5wrPlX1yFmP2adgmXKHc78bsU+j9ZRT3HzzE+D0n7tjuYdo5h38X47/q+UWD1nE0tw/gktEC66gdN/tG0Dc4hnEHhdG7DujOdqGHxi4ae2AZti8ccJXZYoOxawRPnjzGwcpmzM8//ntOe86MickZTEw7ka+99nJAZ/8YWjqs7ufc6ibM/fbQ/fzHo0eoOduJ8UkKljt2nLhk9hj4/Wlm6VA9A2NUa/ew6wNQE1OzVGvPEGUZvkvZHVNUo2mA6ugfpvoGrNT8/Dz1tMfd/yJgKZ13h6zjzFbzvbwO8wDZaR4kzeZbZG/fIHnTbCOvdzrI9h472dnVT97oociO23NkW+9M3pDVsc/V69rjRYA7Su11/dvbfkRJvDeOcMORuj8CpelLkJO6BVs4vQhj3QD5fTQS2PXYndQAblw2yrUt9c/6/xeoqzulK+VEoCTtawgSM5HCr0Nsmg48ngJhYiukonNIybeg8MQEFIZBFBWIoa4z1XoMaOrbtbHci2BtW4RachnOlO/GZW0SjuZEY2eWGYVEFfYJ+kDo/4ThdDPExadQcbxb5zmgb6/xYZlAxPtDmByFS2U+EHM5yBOyEZZ8HkzeZaQmyxFZROGkgUQIMQSNvkPrMXBM31YdFqNDJK8ZHE4FYgSt2Jl0GpKUGAhFjTiQ2QJDgRBGdSTIvEJ8IXDSQJvngEbfWrWacGJDzn1sJ34FkSqFQbgWTcUrcLWIATlnBzYSE8hOOIBQzk9YK56jgRs1CzlBVXD6bcijCYSwTYjhXUFD7nrUlHyFc6pPUCL4BpskUwhn6iGPSMYG3igN3KxeCKDZyulGddReBKV3YbNkGidkIWhQLMeFiuUoE3ths8iOfXFnoQ5nwTt9xHVFVZ5f0XGjxks0A++sIWyNqYM0TYp6qS9+UHxOn+BjqMQfwF8wgg2x5+ErccCboKA5bloAUGc8tk40i2CmGuGhgQhjX0MZwUY5uRJVuX6QcpPhm2TErlBfBLAa4S2epYHrlZ5fke4K6SVyIjRejz1REfhO2Ab2wavgZJ8EU9gEUek1MDMvIIa5DUFpzVhHzECtbRR4DJRrDP5f8h04ILwAmTQLAkEWCgsLIJVIIcwS4uhRBSQSCfi8FGzP6sbKjLsoV+tWewwolUfe+pR1y7GD1YDd4cGIi4uFgM/HulWr4LdpI5ITE5EQH49dOwMRmtmND/ebLMoy+WueA2VyBmO9opSTcx6HimWQHypGBicF+6MjwdzzLSQEH6UlBSjKFyNS1AnGMm6Csuwww2NApVK6hkv2JMptmTkGiPNqEcc+jFiuGsy0SrD4lciQ1kJW3ICAqJIWeu1ilUq1EEDlHr/6vr/XxozBuQD6jw6UUXRm6DgRQCeQfIA1iaZ+BuP191xrXwpw1RtL16zwSfi5PVg2hZAcyp0gqQOr9548TU+/82zdywGvLH429eZnO8rPBNMbB4ps+MhPpvyna9ELgb8ASvKZeuq+E9sAAAAASUVORK5CYII="},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","endDate":"2011-01-01T00:00:00.000Z","startDate":"2011-01-01T00:00:00.000Z","scaleExtent":[14,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 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","endDate":"2014-01-01T00:00:00.000Z","startDate":"2014-01-01T00:00:00.000Z","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"},{"id":"Aargau-AGIS-2016","name":"Kanton Aargau 25cm (AGIS 2016)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/AGIS2016/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","endDate":"2016-01-01T00:00:00.000Z","startDate":"2016-01-01T00:00:00.000Z","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 OF2016","best":true},{"id":"Basel-Landschaft-2015","name":"Kanton Basel-Landschaft 10cm (2015)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTBASELLANDSCHAFT2015/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[18,21],"polygon":[[[7.370281219482422,47.413684985326796],[7.357578277587891,47.41507892620101],[7.357921600341797,47.41827323486739],[7.353544235229492,47.4196089792119],[7.344875335693359,47.42402250214274],[7.339725494384765,47.42971307765559],[7.332687377929687,47.430235650685475],[7.32685089111328,47.4319194618196],[7.325280543317693,47.43489176778178],[7.33050406703179,47.44175856152086],[7.338990092194756,47.44109169292469],[7.344964876980962,47.43607806019703],[7.352656881264292,47.43435807026775],[7.38119797480828,47.432081698142134],[7.375988960266113,47.414309359238985],[7.378145456314087,47.41399717320828],[7.382040023803711,47.41330745332341],[7.388391494750976,47.41397539271845],[7.413708184603623,47.410929293287566],[7.420743520414262,47.411098781635985],[7.427483310496426,47.41448047082256],[7.438105529405026,47.412739349590474],[7.448396898794484,47.41507114537187],[7.455576414208223,47.42792319548619],[7.45061852232364,47.43534476535272],[7.437842682352891,47.446323188615104],[7.425422575234655,47.443283894442736],[7.420904049355535,47.44594415975335],[7.422417620777747,47.45071647996838],[7.428795928789581,47.45387944195848],[7.430028776685507,47.459491697398036],[7.445765194338128,47.46197276972992],[7.44717015944249,47.456958090215814],[7.456512189239691,47.44925575541638],[7.492356675875099,47.458972279610066],[7.530679075390223,47.46118857622267],[7.527445320030451,47.473906165741866],[7.536326693749955,47.48383279861684],[7.536231113003725,47.49105266753894],[7.532603895549507,47.490968962664795],[7.531789123586811,47.49739885661967],[7.520038351186771,47.49678264400428],[7.512226152318425,47.49891674929323],[7.509348758631863,47.508884893812876],[7.499082452238831,47.51627805213703],[7.497870355425969,47.52124757864722],[7.502278119030558,47.514906577969604],[7.517459288006065,47.51728104695845],[7.522200236749534,47.514091442409054],[7.530955756497733,47.52904526885427],[7.519353655277215,47.53471778813415],[7.510751927105658,47.528989768842564],[7.50229842095598,47.52840455858729],[7.4980383403841,47.536152181750076],[7.505454651706732,47.54438188661593],[7.516758242758337,47.545408295649786],[7.527317399933993,47.552778846515565],[7.554658254426867,47.564368052237306],[7.5645783501094,47.55703599040843],[7.561243624111692,47.55172275211291],[7.558752685660356,47.55235329499035],[7.555882119169953,47.54433555917895],[7.564785321950861,47.54568625396918],[7.587263056821628,47.54190064304111],[7.582688476068778,47.53246814131337],[7.589482524394103,47.5279230654027],[7.590248428005343,47.51978966346127],[7.594781326929009,47.51929395578897],[7.613780785019665,47.53925099543145],[7.622303281783164,47.53977428916004],[7.622854488041502,47.550040256825795],[7.617740918118178,47.554366555487356],[7.617617220103555,47.558648485827725],[7.632727781497729,47.5614887674157],[7.639973682410965,47.55816478484801],[7.648995462809379,47.548295861439875],[7.661308760240334,47.544832242956765],[7.665860164458853,47.53745814872834],[7.674674254363578,47.5337535789565],[7.694938989531916,47.532496041115465],[7.71346844906592,47.53978344629896],[7.715956243413761,47.53582195507857],[7.723622825374551,47.536754165368905],[7.727157067196862,47.53293048764033],[7.733221863174538,47.53275465944404],[7.737974130690588,47.52732498381306],[7.749022330706917,47.5249849998809],[7.757861753102653,47.52605097450287],[7.787633628417415,47.52011695778467],[7.790143521321244,47.51864117486466],[7.788870069574476,47.50682929074843],[7.792799480290271,47.500684271209245],[7.786625359342518,47.49312139201968],[7.798890147748131,47.49565149600841],[7.798162871694108,47.49939947973339],[7.799400121334925,47.497477088945935],[7.807418124234862,47.4971384859743],[7.814709929059118,47.504801278976316],[7.831976267472122,47.51473657456054],[7.833207588232065,47.53382387257594],[7.846527268275818,47.53266095290337],[7.852330295179702,47.53523506225097],[7.862569292788096,47.52692027402488],[7.86395674074442,47.519309183202445],[7.876658649367283,47.52269034821798],[7.87567113137545,47.51319304945735],[7.893993798731052,47.50605656803392],[7.904769180395594,47.49217505264052],[7.904821911502771,47.48490926161113],[7.93328835504665,47.48140776210853],[7.947015241408695,47.48488995686335],[7.940027875634228,47.462021295570224],[7.948854362289874,47.46377967418039],[7.957614193951437,47.45880646812721],[7.957849013566705,47.451279351685564],[7.946784554043733,47.44319336966537],[7.950032053627354,47.431716361052416],[7.96183169437885,47.421834282667845],[7.956570351591289,47.41968057428149],[7.955037646053525,47.415605646331336],[7.948388855309641,47.4162657867356],[7.934927870271696,47.41176694218953],[7.936722434714782,47.408057452805856],[7.932661510641391,47.40527495151619],[7.909737672400531,47.398520997340924],[7.890221593189976,47.407141074214024],[7.883331964118422,47.40609724771633],[7.883443085719068,47.4012049891245],[7.877702761222016,47.401257097623],[7.869136696167237,47.3955142728722],[7.879434713089799,47.38799354849815],[7.878812180597903,47.38351047538804],[7.862650230995195,47.38198499163919],[7.840119046365023,47.374763282921705],[7.830547227518145,47.36512144155488],[7.80216648325237,47.36109584064414],[7.796366151294341,47.3534705803715],[7.793560892325092,47.33905227137494],[7.78528803737905,47.3378822997136],[7.768963133383802,47.33891408469915],[7.766419194330703,47.342734660857005],[7.751518928544542,47.3443274446774],[7.734153146629586,47.35776074638933],[7.727913718160677,47.36885889855421],[7.701953574259492,47.37244716296033],[7.644203220263186,47.36720838530677],[7.641761060331779,47.38046937860509],[7.635580022356337,47.38059279713257],[7.633316986492583,47.38291397270416],[7.633305398225418,47.38533959871929],[7.637251158279386,47.38606854199808],[7.63272275093214,47.41003108104519],[7.664054730400831,47.41001995588381],[7.679802017668389,47.41751395224505],[7.686578998003315,47.43366406703297],[7.682972441800632,47.43872228466388],[7.684853783500164,47.447843589969715],[7.692273418589347,47.45421309996921],[7.698831030331891,47.45585888435835],[7.699930658071183,47.46190517358485],[7.709877972706822,47.469384739707586],[7.699760966314013,47.48063247960835],[7.668326578902932,47.48634665620256],[7.666120855554305,47.49686816039971],[7.65217109717027,47.49581439933043],[7.648646287658441,47.49183004211102],[7.655389581170213,47.49020559719241],[7.650513795302598,47.48826095607083],[7.655925875394832,47.48739459757455],[7.644422678687097,47.485637798180356],[7.640965961473804,47.482734093980326],[7.607299799570857,47.48939839412024],[7.608850381582776,47.48352506892989],[7.605631268762133,47.47935909729055],[7.608148977008936,47.475213682276376],[7.604494899927722,47.47044546774548],[7.618872436050056,47.4674530520825],[7.626072253389216,47.462913883669614],[7.62217338539308,47.46195224188912],[7.616464591762502,47.445234574416695],[7.615798850305441,47.432747890966844],[7.592069133423196,47.43271179535717],[7.581206884670679,47.42878068945942],[7.578423275099778,47.434906655087865],[7.568904367023134,47.43689695884281],[7.56829539909203,47.42233486107083],[7.58074128785892,47.414703988151935],[7.525235194936931,47.41163289737562],[7.531172340312734,47.40352507464003],[7.518616677418122,47.38822295597742],[7.511295677347134,47.38974369796625],[7.502255661148456,47.384806980223004],[7.492327480628366,47.385231761698726],[7.478410241257615,47.39055778320416],[7.47746817801916,47.401277162725364],[7.464484018734026,47.40251498235377],[7.460919593518167,47.40068414452088],[7.450020783333588,47.40392739156406],[7.44951323519806,47.39975827367453],[7.443401098004909,47.40231427489849],[7.441311347159463,47.40017886074712],[7.443566657511773,47.38890284041263],[7.437324174770898,47.3808884773088],[7.411692544769116,47.38057235919037],[7.416276198506335,47.384788794341716],[7.414494030814171,47.39429988358522],[7.398935569419335,47.39683906243558],[7.395920463999715,47.40338304393273],[7.388693876865087,47.403019088497395],[7.384054886906365,47.4123601395877],[7.379679679870605,47.4128137535428],[7.375844120979309,47.41401169352981],[7.370281219482422,47.413684985326796]]],"terms_url":"http://www.geo.bl.ch/fileadmin/user_upload/Geodaten/Nutzungsbedingungen_GBD_BL_V3p1.pdf","terms_text":"Geodaten des Kantons Basel-Landschaft 2015","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":[15,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,"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAIVBMVEX///+LKCbMAABycnL+/v7v7+9sbGz39/fz8/Pw8PD8/Pz60siYAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+AIGAsXN84mS+sAAAA4SURBVAjXY2AUBAMBBkYlMCCXwcwABgZYGCwGIJo5AMQGAjYgLgYxLICY05iBwRisjsvY2IGBAQAGpQmjMKkg/wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wOC0yNFQxMToyMzo1NS0wNDowMLEFqzIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDgtMjRUMTE6MjM6NTUtMDQ6MDDAWBOOAAAAAElFTkSuQmCC"},{"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","endDate":"2012-05-14T00:00:00.000Z","startDate":"2012-05-13T00:00:00.000Z","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]]],"description":"High quality aerial imagery taken for the City of Kelowna"},{"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","endDate":"2013-09-03T00:00:00.000Z","startDate":"2013-09-03T00:00:00.000Z","scaleExtent":[5,14],"polygon":[[[-60.8550011,6.1765004],[-60.4762612,7.9188291],[-62.161689,8.2778675],[-62.5322549,6.5375488],[-60.8550011,6.1765004]]],"description":"Recent Landsat imagery"},{"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","endDate":"2013-09-12T00:00:00.000Z","startDate":"2013-09-12T00:00:00.000Z","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]]],"description":"Recent lower-resolution landsat imagery for southwest British Columbia"},{"id":"LINZ_NZ_Aerial_Imagery","name":"LINZ NZ Aerial Imagery","type":"tms","template":"https://tiles-a.data-cdn.linz.govt.nz/services;key=3197c6d0e5cb494a95d58dc2de3216c2/tiles/v4/set=2/EPSG:3857/{zoom}/{x}/{y}.png","scaleExtent":[0,21],"polygon":[[[167.2503662109375,-47.21956811231548],[167.244873046875,-47.28016067076474],[167.5030517578125,-47.37975438400816],[168.2501220703125,-47.15610477504402],[168.7445068359375,-46.79629898997744],[169.3267822265625,-46.75491661928188],[169.78271484375,-46.604167162931844],[170.4254150390625,-46.11132565729794],[170.804443359375,-45.95114968669139],[170.9527587890625,-45.440862671781744],[171.309814453125,-44.91035917458493],[171.40869140625,-44.39061697878681],[172.562255859375,-43.92954993561458],[172.90283203125,-43.96909818325171],[173.1610107421875,-43.90976594390799],[173.2598876953125,-43.69567969789881],[172.9742431640625,-43.53660274231031],[172.760009765625,-43.37710501700071],[173.1500244140625,-43.17714134663171],[173.704833984375,-42.63395872267314],[174.36401367187497,-41.78360106648077],[174.320068359375,-41.409775832009544],[174.84741210937497,-41.52914198872309],[175.0726318359375,-41.70572851523751],[175.506591796875,-41.672911819602085],[176.2261962890625,-41.10832999732831],[176.8304443359375,-40.42604212826493],[177.17102050781247,-39.67337039176559],[177.0391845703125,-39.39375459224347],[177.4456787109375,-39.18117526158747],[177.60498046875,-39.3300485529424],[177.978515625,-39.368279149160124],[178.3355712890625,-38.65977773071253],[178.7091064453125,-37.74465712069938],[178.626708984375,-37.54457732085582],[178.3135986328125,-37.43125050179357],[177.6214599609375,-37.37888785004525],[177.0391845703125,-37.39634613318924],[176.561279296875,-37.37015718405751],[176.3360595703125,-37.05956083025124],[176.0064697265625,-36.29741818650809],[175.6768798828125,-36.05354012833974],[174.671630859375,-35.1782983520012],[173.1939697265625,-34.28445325435288],[172.6776123046875,-34.234512362369856],[172.386474609375,-34.40237742424137],[172.4798583984375,-34.71903991764788],[172.9852294921875,-35.32184842037683],[173.56201171875,-36.142310873529986],[174.30908203125,-37.077093191754415],[174.5562744140625,-38.052416771864834],[174.4793701171875,-38.655488159952995],[174.3255615234375,-38.865374851611634],[173.7982177734375,-38.95940879245421],[173.60595703125,-39.232253141714885],[173.6993408203125,-39.56335316582929],[174.5892333984375,-39.95606977009003],[174.9847412109375,-40.216635475391215],[174.9847412109375,-40.49291502689579],[174.7210693359375,-40.805493843894155],[174.1497802734375,-40.65147128144056],[173.2818603515625,-40.43440488077009],[172.5897216796875,-40.350730565917885],[172.0843505859375,-40.534676780615406],[171.7657470703125,-40.826280356677124],[171.57348632812497,-41.3974150664646],[171.2823486328125,-41.652392884268124],[170.8758544921875,-42.53284428171312],[170.35400390625,-42.87193842444846],[168.277587890625,-43.92954993561458],[167.6239013671875,-44.47691085722324],[166.55273437499997,-45.38687734827038],[166.27258300781247,-45.916765867649],[166.4813232421875,-46.22545288226937],[167.6788330078125,-46.471916320870406],[167.2503662109375,-47.21956811231548]]],"terms_url":"http://www.linz.govt.nz/data/licensing-and-using-data/attributing-elevation-or-aerial-imagery-data","terms_text":"Sourced from LINZ CC-BY 3.0","best":true},{"id":"LINZ_NZ_Topo50_Gridless_Maps","name":"LINZ NZ Topo50 Gridless Maps","type":"tms","template":"https://tiles-a.data-cdn.linz.govt.nz/services;key=3197c6d0e5cb494a95d58dc2de3216c2/tiles/v4/layer=2343/EPSG:3857/{zoom}/{x}/{y}.png","scaleExtent":[0,21],"polygon":[[[167.2503662109375,-47.21956811231548],[167.244873046875,-47.28016067076474],[167.5030517578125,-47.37975438400816],[168.2501220703125,-47.15610477504402],[168.7445068359375,-46.79629898997744],[169.3267822265625,-46.75491661928188],[169.78271484375,-46.604167162931844],[170.4254150390625,-46.11132565729794],[170.804443359375,-45.95114968669139],[170.9527587890625,-45.440862671781744],[171.309814453125,-44.91035917458493],[171.40869140625,-44.39061697878681],[172.562255859375,-43.92954993561458],[172.90283203125,-43.96909818325171],[173.1610107421875,-43.90976594390799],[173.2598876953125,-43.69567969789881],[172.9742431640625,-43.53660274231031],[172.760009765625,-43.37710501700071],[173.1500244140625,-43.17714134663171],[173.704833984375,-42.63395872267314],[174.36401367187497,-41.78360106648077],[174.320068359375,-41.409775832009544],[174.84741210937497,-41.52914198872309],[175.0726318359375,-41.70572851523751],[175.506591796875,-41.672911819602085],[176.2261962890625,-41.10832999732831],[176.8304443359375,-40.42604212826493],[177.17102050781247,-39.67337039176559],[177.0391845703125,-39.39375459224347],[177.4456787109375,-39.18117526158747],[177.60498046875,-39.3300485529424],[177.978515625,-39.368279149160124],[178.3355712890625,-38.65977773071253],[178.7091064453125,-37.74465712069938],[178.626708984375,-37.54457732085582],[178.3135986328125,-37.43125050179357],[177.6214599609375,-37.37888785004525],[177.0391845703125,-37.39634613318924],[176.561279296875,-37.37015718405751],[176.3360595703125,-37.05956083025124],[176.0064697265625,-36.29741818650809],[175.6768798828125,-36.05354012833974],[174.671630859375,-35.1782983520012],[173.1939697265625,-34.28445325435288],[172.6776123046875,-34.234512362369856],[172.386474609375,-34.40237742424137],[172.4798583984375,-34.71903991764788],[172.9852294921875,-35.32184842037683],[173.56201171875,-36.142310873529986],[174.30908203125,-37.077093191754415],[174.5562744140625,-38.052416771864834],[174.4793701171875,-38.655488159952995],[174.3255615234375,-38.865374851611634],[173.7982177734375,-38.95940879245421],[173.60595703125,-39.232253141714885],[173.6993408203125,-39.56335316582929],[174.5892333984375,-39.95606977009003],[174.9847412109375,-40.216635475391215],[174.9847412109375,-40.49291502689579],[174.7210693359375,-40.805493843894155],[174.1497802734375,-40.65147128144056],[173.2818603515625,-40.43440488077009],[172.5897216796875,-40.350730565917885],[172.0843505859375,-40.534676780615406],[171.7657470703125,-40.826280356677124],[171.57348632812497,-41.3974150664646],[171.2823486328125,-41.652392884268124],[170.8758544921875,-42.53284428171312],[170.35400390625,-42.87193842444846],[168.277587890625,-43.92954993561458],[167.6239013671875,-44.47691085722324],[166.55273437499997,-45.38687734827038],[166.27258300781247,-45.916765867649],[166.4813232421875,-46.22545288226937],[167.6788330078125,-46.471916320870406],[167.2503662109375,-47.21956811231548]]],"terms_url":"https://data.linz.govt.nz/layer/2343-nz-mainland-topo50-gridless-maps/","terms_text":"Sourced from the LINZ Data Service and licensed by LINZ for re-use under the Creative Commons Attribution 3.0 New Zealand licence."},{"id":"ORT10LT","name":"Lithuania - NŽT ORT10LT","type":"tms","template":"http://ort10lt.openmap.lt/g16/{zoom}/{x}/{y}.jpeg","endDate":"2016-01-01T00:00:00.000Z","startDate":"2010-01-01T00:00:00.000Z","scaleExtent":[4,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","best":true},{"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","scaleExtent":[0,16],"overzoom":false,"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true,"description":"Shows major features to help orient you.","overlay":true},{"id":"londrina2011","name":"Londrina Ortofoto 2011","type":"tms","template":"https://siglon.londrina.pr.gov.br/arcgis/rest/services/Imagens/Ortofotos_2011_Paranacidade/MapServer/WMTS/tile/1.0.0/Imagens_Ortofotos_2011_Paranacidade/default/GoogleMapsCompatible/{zoom}/{y}/{x}","polygon":[[[-51.10903142008701,-23.392750890870328],[-51.110147219037096,-23.39111628244602],[-51.111981850003126,-23.389599820448623],[-51.11358044657587,-23.38976722295012],[-51.120999436701226,-23.38592675938185],[-51.12224934611127,-23.385109415587607],[-51.12483499560139,-23.383504255873166],[-51.12538216624037,-23.38186953335707],[-51.12482426676533,-23.37770385409619],[-51.12445948633935,-23.375054689723584],[-51.124373655650885,-23.372297138974446],[-51.12244246516032,-23.37032742475139],[-51.12302182230749,-23.366427304263887],[-51.128557901713755,-23.36548180323493],[-51.12832186732048,-23.358843408308623],[-51.12477062258506,-23.35475580404945],[-51.12703440699343,-23.35091432623551],[-51.12411616358548,-23.34679692655685],[-51.12025378260435,-23.347811512977742],[-51.1176466754421,-23.33969460448754],[-51.11264703783877,-23.341290443649072],[-51.109396200513004,-23.33488726938344],[-51.10756156954697,-23.334089313725826],[-51.10485790286019,-23.333980949007543],[-51.10252974543546,-23.334187827029368],[-51.09986899409291,-23.331015661953632],[-51.09801290545476,-23.329360589233605],[-51.09998701128955,-23.32830645478855],[-51.10322711977927,-23.325321337105603],[-51.10472915682748,-23.323193291476684],[-51.104664783811145,-23.321291814470847],[-51.10514758143378,-23.318444474199904],[-51.1063599399084,-23.3157547161216],[-51.10660670313775,-23.31467091543279],[-51.11050127062705,-23.311665785493048],[-51.111584883068964,-23.30842411016493],[-51.099504213666904,-23.309468549142686],[-51.09740136179941,-23.308631027972474],[-51.09511611971892,-23.307448636164267],[-51.09201548609798,-23.3049360186679],[-51.09036324534495,-23.3037141796735],[-51.09204767260616,-23.29874787986134],[-51.09269140276969,-23.297496421894902],[-51.09407542262125,-23.292953629109174],[-51.10073802981369,-23.293318240761657],[-51.10101697955121,-23.28870632248831],[-51.10068438563339,-23.28837126237015],[-51.10084531817427,-23.28777997775132],[-51.09937546763423,-23.28663682004102],[-51.09631774935752,-23.277914991984613],[-51.10285161051725,-23.273016720553397],[-51.10835550341534,-23.27033590016574],[-51.11309764895328,-23.268404099092194],[-51.13160489115448,-23.265338785827712],[-51.13188384089201,-23.262007272160396],[-51.1317336371872,-23.255058136908826],[-51.13290308031759,-23.254683563301587],[-51.132956724497895,-23.250750476893938],[-51.13473771128364,-23.2512729236245],[-51.13533852610292,-23.25133206840842],[-51.13516686472599,-23.24359373640034],[-51.13534925493897,-23.24117849627157],[-51.137516479822814,-23.24219388826517],[-51.13884685549409,-23.243495156026544],[-51.14108918223035,-23.24521044413634],[-51.1471724322756,-23.243179698340864],[-51.14761231455401,-23.23828015040167],[-51.149082165094036,-23.235884531292832],[-51.14976881060179,-23.236811236789336],[-51.15138886484666,-23.23853646924079],[-51.15289090189487,-23.238842079520833],[-51.15383503946804,-23.238950521710013],[-51.15820167574391,-23.238142132361276],[-51.16045473131624,-23.238161849232945],[-51.160347442955654,-23.24658068718069],[-51.15912435564498,-23.2478326235554],[-51.16131303820094,-23.247773477219496],[-51.166591625541805,-23.245939927797],[-51.17193458589902,-23.245821633420345],[-51.17205260309565,-23.249557713480034],[-51.174241285651625,-23.248404370116877],[-51.17514250788055,-23.2493211310392],[-51.176859121649926,-23.248157927934038],[-51.179466228812196,-23.251686936561047],[-51.18135450395853,-23.253806268366073],[-51.18273852381009,-23.253628837227893],[-51.18378994974384,-23.253264116924615],[-51.18495939287424,-23.253303546194683],[-51.18626831087339,-23.252150235227905],[-51.18665454897149,-23.247477745146526],[-51.191182117788244,-23.249143693933142],[-51.19141815218154,-23.252859966234126],[-51.19369266542598,-23.252781107419985],[-51.1938428691308,-23.26073575534214],[-51.20096681627374,-23.26054847664639],[-51.20126722368338,-23.24259807127726],[-51.209936123218775,-23.242775517090898],[-51.21090171846407,-23.26988252079656],[-51.21968863519614,-23.27221839365197],[-51.225965004290465,-23.2745345140599],[-51.22934458764894,-23.27860487489667],[-51.234515886629225,-23.28160089636689],[-51.23497722657975,-23.283246708422755],[-51.235073786104266,-23.285444377831148],[-51.23371122392482,-23.285897704227196],[-51.232155542696304,-23.28801649191402],[-51.22870085748543,-23.292293383844925],[-51.227402668322334,-23.294599300809004],[-51.22679112466699,-23.295476327114592],[-51.225600223864475,-23.29657013833941],[-51.22392652543933,-23.297210654251764],[-51.220482569064515,-23.30072850975029],[-51.21863720926242,-23.301300029310937],[-51.21668456109974,-23.30211788923888],[-51.21423838647836,-23.30441378240661],[-51.210966091480465,-23.306965823153238],[-51.22328279527583,-23.318296686707587],[-51.224387865389886,-23.31459209321986],[-51.22521398576639,-23.312887551432937],[-51.22511742624187,-23.312582111000477],[-51.22521398576639,-23.312513140483127],[-51.2255251220121,-23.312532846348883],[-51.22595427545445,-23.312385052284572],[-51.22616885217561,-23.31183328632629],[-51.22935531648505,-23.314887676277397],[-51.22802494081377,-23.31661189768144],[-51.227885465945,-23.31901591762422],[-51.22767088922384,-23.320227763653186],[-51.22723100694544,-23.321508564518947],[-51.2273919394863,-23.322227778055023],[-51.22725246461755,-23.322848466059934],[-51.230331640566384,-23.325577488448165],[-51.23046038659909,-23.326710459617892],[-51.229537706698046,-23.32789268010374],[-51.229162197436,-23.330503379743732],[-51.229290943468705,-23.33178408156439],[-51.22681258233914,-23.334473515196468],[-51.2260186484708,-23.336571826694826],[-51.22473118814376,-23.33839427691611],[-51.22210262330938,-23.340226553005806],[-51.22257469209598,-23.34196029634743],[-51.22380850824271,-23.343388647432523],[-51.22384069475089,-23.345309509145306],[-51.22440932306201,-23.347003784611864],[-51.2245380690947,-23.348294177581966],[-51.22404454263601,-23.34968305981433],[-51.22350810083308,-23.35010661675208],[-51.22381923707877,-23.35076657486812],[-51.22304676088255,-23.35174173085325],[-51.22259614976809,-23.35296312824164],[-51.22586844476598,-23.35480505304304],[-51.22650144609346,-23.36705763453823],[-51.22354028734128,-23.369145582171885],[-51.22366903337377,-23.37968330666716],[-51.220375280703756,-23.381633186264455],[-51.216469984378406,-23.38170212087667],[-51.21416328462579,-23.379949201028825],[-51.2092816642191,-23.37395167630701],[-51.20738266023672,-23.368141007697016],[-51.20628831895872,-23.36723491438801],[-51.20472190889416,-23.366269721227162],[-51.198230963078665,-23.366683376299132],[-51.19297383340994,-23.366506095711998],[-51.18986247095292,-23.3654424072124],[-51.18806002649507,-23.36464463523902],[-51.18718026193825,-23.3645264463904],[-51.18579624208668,-23.363738518041337],[-51.183038931219606,-23.36359078095478],[-51.18071077379488,-23.3637582163071],[-51.179069261877906,-23.361581540240305],[-51.177642326682125,-23.35836078207346],[-51.16683838877106,-23.356262814974126],[-51.166141014427254,-23.358538073547532],[-51.16475699457568,-23.360389770338585],[-51.16076586756186,-23.359217688669915],[-51.15983245882475,-23.36660458495632],[-51.162042599052846,-23.36861374957437],[-51.16276143106877,-23.374158492021696],[-51.158448438973174,-23.37580315788644],[-51.155047397942575,-23.376305417047273],[-51.15396378550066,-23.37903334042617],[-51.15298746141932,-23.381052164536694],[-51.15118501696147,-23.382076336717283],[-51.149167995782435,-23.382509637949354],[-51.14721534761976,-23.382155118864866],[-51.14517686876862,-23.382588419839323],[-51.14410398516276,-23.38376029492248],[-51.14512322458833,-23.388083341091015],[-51.141797285410156,-23.389402876058366],[-51.14030597719799,-23.38880219385971],[-51.14068148646006,-23.391608636504017],[-51.14127157244328,-23.393538646762796],[-51.14093897852546,-23.394434713394368],[-51.140456180902824,-23.39536031431835],[-51.13939402613302,-23.395104297688697],[-51.13738773379004,-23.393154616350518],[-51.13608954462695,-23.389796764546077],[-51.13428710016909,-23.389757375749994],[-51.132162790629465,-23.390072485790583],[-51.13172290835106,-23.39285920758337],[-51.12259266886514,-23.38864463742227],[-51.12228153261944,-23.391657871809155],[-51.11882684740854,-23.393174310244916],[-51.115683298443365,-23.393351555162592],[-51.10903142008701,-23.392750890870328]],[[-51.13829432042955,-23.41600741009485],[-51.133310776080314,-23.418665600378624],[-51.132087688769644,-23.416440600302334],[-51.13002238782791,-23.418291487939495],[-51.12868664773901,-23.419010176689888],[-51.12824140104259,-23.42102839134528],[-51.12696466955051,-23.421860280620358],[-51.12532852205271,-23.422692164660027],[-51.1244541219139,-23.420969322085504],[-51.1215144208339,-23.424109801147612],[-51.12063465627703,-23.423268081315832],[-51.11970661195797,-23.423120410617486],[-51.11977098497433,-23.42156985833077],[-51.1188000253111,-23.421545246243184],[-51.11643431696008,-23.420836416154565],[-51.11942766222045,-23.419167696990424],[-51.11787198099193,-23.416775337218567],[-51.116546969738685,-23.41730697646229],[-51.115699391690086,-23.415702207051474],[-51.115120034542905,-23.413088261827834],[-51.119078975048524,-23.411114231305813],[-51.119599323597356,-23.41169512115064],[-51.12052200349841,-23.41489489238112],[-51.12147686990764,-23.417139608782644],[-51.12308619531643,-23.418626220171642],[-51.12754939111684,-23.41653905242448],[-51.12803218873949,-23.417395582795194],[-51.13119719537679,-23.415574218468866],[-51.13080022844262,-23.414766903017576],[-51.13278506311348,-23.41264029239725],[-51.13521514448077,-23.411055157619415],[-51.13585887464424,-23.410956701416854],[-51.13682446988958,-23.411188073376714],[-51.137205343569626,-23.411576974270133],[-51.13730190309418,-23.41324086645236],[-51.137430649126884,-23.414707830961888],[-51.13829432042955,-23.41600741009485]],[[-51.18929065852,-23.61469318354],[-51.18868716149,-23.61385268133],[-51.18817754178,-23.61338573333],[-51.18731118826,-23.61301708899],[-51.18628926663,-23.61314488581],[-51.18401743559,-23.61395590119],[-51.18348904042,-23.61396573165],[-51.18183143525,-23.61283522407],[-51.18140496401,-23.61344471632],[-51.18062980561,-23.61313505529],[-51.18001021533,-23.61409352754],[-51.17865838198,-23.61328742827],[-51.18064589886,-23.61060367181],[-51.17972321896,-23.61018095058],[-51.18061639456,-23.60849005203],[-51.1821157494,-23.60850479833],[-51.18260927586,-23.60775273479],[-51.18319936184,-23.60804274673],[-51.18415154605,-23.60627808786],[-51.18511177687,-23.60666149766],[-51.18649043231,-23.60469528171],[-51.18902243762,-23.60610112912],[-51.18821241049,-23.60741848294],[-51.18918873458,-23.60801816947],[-51.188899056,-23.60953211999],[-51.18962325244,-23.60992535103],[-51.1911896625,-23.6111935131],[-51.1901489654,-23.61244691705],[-51.19054056792,-23.6127565797],[-51.19029380469,-23.61377895281],[-51.18929065852,-23.61469318354]],[[-51.08005769639,-23.52984412096],[-51.07962317853,-23.52205317842],[-51.08468182473,-23.52194496764],[-51.08581908135,-23.52404030606],[-51.0858941832,-23.52703569673],[-51.08579494147,-23.52777346722],[-51.08530141501,-23.52806365581],[-51.08513511805,-23.52856533627],[-51.08512438922,-23.52981952906],[-51.08470864682,-23.53023759067],[-51.08343459754,-23.53023759067],[-51.08329512267,-23.52978018202],[-51.08005769639,-23.52984412096]]],"terms_url":"http://siglon.londrina.pr.gov.br/","terms_text":"Prefeitura do Londrinas, PR"},{"id":"NSW_LPI_BaseMap","name":"LPI NSW Base Map","type":"tms","template":"https://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 2017"},{"id":"NSW_LPI_Imagery","name":"LPI NSW Imagery","type":"tms","template":"https://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 2017","best":true},{"id":"NSW_LPI_TopographicMap","name":"LPI NSW Topographic Map","type":"tms","template":"https://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 2017"},{"id":"Mapbox","name":"Mapbox Satellite","type":"tms","template":"https://{switch:a,b,c}.tiles.mapbox.com/v4/openstreetmap.map-inh7ifmo/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","scaleExtent":[0,19],"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true,"description":"Satellite and aerial imagery.","icon":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgODAuNDcgMjAuMDIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDgwLjQ3IDIwLjAyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe29wYWNpdHk6MC42O2ZpbGw6I0ZGRkZGRjtlbmFibGUtYmFja2dyb3VuZDpuZXcgICAgO30uc3Qxe29wYWNpdHk6MC42O2VuYWJsZS1iYWNrZ3JvdW5kOm5ldyAgICA7fTwvc3R5bGU+PGc+PHBhdGggY2xhc3M9InN0MCIgZD0iTTc5LjI5LDEzLjYxYzAsMC4xMS0wLjA5LDAuMi0wLjIsMC4yaC0xLjUzYy0wLjEyLDAtMC4yMy0wLjA2LTAuMjktMC4xNmwtMS4zNy0yLjI4bC0xLjM3LDIuMjhjLTAuMDYsMC4xLTAuMTcsMC4xNi0wLjI5LDAuMTZoLTEuNTNjLTAuMDQsMC0wLjA4LTAuMDEtMC4xMS0wLjAzYy0wLjA5LTAuMDYtMC4xMi0wLjE4LTAuMDYtMC4yN2MwLDAsMCwwLDAsMGwyLjMxLTMuNWwtMi4yOC0zLjQ3Yy0wLjAyLTAuMDMtMC4wMy0wLjA3LTAuMDMtMC4xMWMwLTAuMTEsMC4wOS0wLjIsMC4yLTAuMmgxLjUzYzAuMTIsMCwwLjIzLDAuMDYsMC4yOSwwLjE2bDEuMzQsMi4yNWwxLjMzLTIuMjRjMC4wNi0wLjEsMC4xNy0wLjE2LDAuMjktMC4xNmgxLjUzYzAuMDQsMCwwLjA4LDAuMDEsMC4xMSwwLjAzYzAuMDksMC4wNiwwLjEyLDAuMTgsMC4wNiwwLjI3YzAsMCwwLDAsMCwwTDc2Ljk2LDEwbDIuMzEsMy41Qzc5LjI4LDEzLjUzLDc5LjI5LDEzLjU3LDc5LjI5LDEzLjYxeiIvPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik02My4wOSw5LjE2Yy0wLjM3LTEuNzktMS44Ny0zLjEyLTMuNjYtMy4xMmMtMC45OCwwLTEuOTMsMC40LTIuNiwxLjEyVjMuMzdjMC0wLjEyLTAuMS0wLjIyLTAuMjItMC4yMmgtMS4zM2MtMC4xMiwwLTAuMjIsMC4xLTAuMjIsMC4yMnYxMC4yMWMwLDAuMTIsMC4xLDAuMjIsMC4yMiwwLjIyaDEuMzNjMC4xMiwwLDAuMjItMC4xLDAuMjItMC4yMnYtMC43YzAuNjgsMC43MSwxLjYyLDEuMTIsMi42LDEuMTJjMS43OSwwLDMuMjktMS4zNCwzLjY2LTMuMTNDNjMuMjEsMTAuMyw2My4yMSw5LjcyLDYzLjA5LDkuMTZMNjMuMDksOS4xNnogTTU5LjEyLDEyLjQxYy0xLjI2LDAtMi4yOC0xLjA2LTIuMy0yLjM2VjkuOTljMC4wMi0xLjMxLDEuMDQtMi4zNiwyLjMtMi4zNnMyLjMsMS4wNywyLjMsMi4zOVM2MC4zOSwxMi40MSw1OS4xMiwxMi40MXoiLz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNNjguMjYsNi4wNGMtMS44OS0wLjAxLTMuNTQsMS4yOS0zLjk2LDMuMTNjLTAuMTIsMC41Ni0wLjEyLDEuMTMsMCwxLjY5YzAuNDIsMS44NSwyLjA3LDMuMTYsMy45NywzLjE0YzIuMjQsMCw0LjA2LTEuNzgsNC4wNi0zLjk5UzcwLjUxLDYuMDQsNjguMjYsNi4wNHogTTY4LjI0LDEyLjQyYy0xLjI3LDAtMi4zLTEuMDctMi4zLTIuMzlzMS4wMy0yLjQsMi4zLTIuNHMyLjMsMS4wNywyLjMsMi4zOVM2OS41MSwxMi40MSw2OC4yNCwxMi40Mkw2OC4yNCwxMi40MnoiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNNTkuMTIsNy42M2MtMS4yNiwwLTIuMjgsMS4wNi0yLjMsMi4zNnYwLjA2YzAuMDIsMS4zMSwxLjA0LDIuMzYsMi4zLDIuMzZzMi4zLTEuMDcsMi4zLTIuMzlTNjAuMzksNy42Myw1OS4xMiw3LjYzeiBNNTkuMTIsMTEuMjNjLTAuNiwwLTEuMDktMC41My0xLjExLTEuMTlWMTBjMC4wMS0wLjY2LDAuNTEtMS4xOSwxLjExLTEuMTlzMS4xMSwwLjU0LDEuMTEsMS4yMVM1OS43NCwxMS4yMyw1OS4xMiwxMS4yM3oiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNNjguMjQsNy42M2MtMS4yNywwLTIuMywxLjA3LTIuMywyLjM5czEuMDMsMi4zOSwyLjMsMi4zOXMyLjMtMS4wNywyLjMtMi4zOVM2OS41MSw3LjYzLDY4LjI0LDcuNjN6IE02OC4yNCwxMS4yM2MtMC42MSwwLTEuMTEtMC41NC0xLjExLTEuMjFzMC41LTEuMiwxLjExLTEuMnMxLjExLDAuNTQsMS4xMSwxLjIxUzY4Ljg1LDExLjIzLDY4LjI0LDExLjIzeiIvPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00My41Niw2LjI0aC0xLjMzYy0wLjEyLDAtMC4yMiwwLjEtMC4yMiwwLjIydjAuN2MtMC42OC0wLjcxLTEuNjItMS4xMi0yLjYtMS4xMmMtMi4wNywwLTMuNzUsMS43OC0zLjc1LDMuOTlzMS42OSwzLjk5LDMuNzUsMy45OWMwLjk5LDAsMS45My0wLjQxLDIuNi0xLjEzdjAuN2MwLDAuMTIsMC4xLDAuMjIsMC4yMiwwLjIyaDEuMzNjMC4xMiwwLDAuMjItMC4xLDAuMjItMC4yMlY2LjQ0YzAtMC4xMS0wLjA5LTAuMjEtMC4yMS0wLjIxQzQzLjU3LDYuMjQsNDMuNTcsNi4yNCw0My41Niw2LjI0eiBNNDIuMDIsMTAuMDVjLTAuMDEsMS4zMS0xLjA0LDIuMzYtMi4zLDIuMzZzLTIuMy0xLjA3LTIuMy0yLjM5czEuMDMtMi40LDIuMjktMi40YzEuMjcsMCwyLjI4LDEuMDYsMi4zLDIuMzZMNDIuMDIsMTAuMDV6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTM5LjcyLDcuNjNjLTEuMjcsMC0yLjMsMS4wNy0yLjMsMi4zOXMxLjAzLDIuMzksMi4zLDIuMzlzMi4yOC0xLjA2LDIuMy0yLjM2VjkuOTlDNDIsOC42OCw0MC45OCw3LjYzLDM5LjcyLDcuNjN6IE0zOC42MiwxMC4wMmMwLTAuNjcsMC41LTEuMjEsMS4xMS0xLjIxYzAuNjEsMCwxLjA5LDAuNTMsMS4xMSwxLjE5djAuMDRjLTAuMDEsMC42NS0wLjUsMS4xOC0xLjExLDEuMThTMzguNjIsMTAuNjgsMzguNjIsMTAuMDJ6Ii8+PHBhdGggY2xhc3M9InN0MCIgZD0iTTQ5LjkxLDYuMDRjLTAuOTgsMC0xLjkzLDAuNC0yLjYsMS4xMlY2LjQ1YzAtMC4xMi0wLjEtMC4yMi0wLjIyLTAuMjJoLTEuMzNjLTAuMTIsMC0wLjIyLDAuMS0wLjIyLDAuMjJ2MTAuMjFjMCwwLjEyLDAuMSwwLjIyLDAuMjIsMC4yMmgxLjMzYzAuMTIsMCwwLjIyLTAuMSwwLjIyLTAuMjJ2LTMuNzhjMC42OCwwLjcxLDEuNjIsMS4xMiwyLjYxLDEuMTJjMi4wNywwLDMuNzUtMS43OCwzLjc1LTMuOTlTNTEuOTgsNi4wNCw0OS45MSw2LjA0eiBNNDkuNiwxMi40MmMtMS4yNiwwLTIuMjgtMS4wNi0yLjMtMi4zNlY5Ljk5YzAuMDItMS4zMSwxLjA0LTIuMzcsMi4yOS0yLjM3YzEuMjYsMCwyLjMsMS4wNywyLjMsMi4zOVM1MC44NiwxMi40MSw0OS42LDEyLjQyTDQ5LjYsMTIuNDJ6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTQ5LjYsNy42M2MtMS4yNiwwLTIuMjgsMS4wNi0yLjMsMi4zNnYwLjA2YzAuMDIsMS4zMSwxLjA0LDIuMzYsMi4zLDIuMzZzMi4zLTEuMDcsMi4zLTIuMzlTNTAuODYsNy42Myw0OS42LDcuNjN6IE00OS42LDExLjIzYy0wLjYsMC0xLjA5LTAuNTMtMS4xMS0xLjE5VjEwQzQ4LjUsOS4zNCw0OSw4LjgxLDQ5LjYsOC44MWMwLjYsMCwxLjExLDAuNTUsMS4xMSwxLjIxUzUwLjIxLDExLjIzLDQ5LjYsMTEuMjN6Ii8+PHBhdGggY2xhc3M9InN0MCIgZD0iTTM0LjM2LDEzLjU5YzAsMC4xMi0wLjEsMC4yMi0wLjIyLDAuMjJoLTEuMzRjLTAuMTIsMC0wLjIyLTAuMS0wLjIyLTAuMjJWOS4yNGMwLTAuOTMtMC43LTEuNjMtMS41NC0xLjYzYy0wLjc2LDAtMS4zOSwwLjY3LTEuNTEsMS41NGwwLjAxLDQuNDRjMCwwLjEyLTAuMSwwLjIyLTAuMjIsMC4yMmgtMS4zNGMtMC4xMiwwLTAuMjItMC4xLTAuMjItMC4yMlY5LjI0YzAtMC45My0wLjctMS42My0xLjU0LTEuNjNjLTAuODEsMC0xLjQ3LDAuNzUtMS41MiwxLjcxdjQuMjdjMCwwLjEyLTAuMSwwLjIyLTAuMjIsMC4yMmgtMS4zM2MtMC4xMiwwLTAuMjItMC4xLTAuMjItMC4yMlY2LjQ0YzAuMDEtMC4xMiwwLjEtMC4yMSwwLjIyLTAuMjFoMS4zM2MwLjEyLDAsMC4yMSwwLjEsMC4yMiwwLjIxdjAuNjNjMC40OC0wLjY1LDEuMjQtMS4wNCwyLjA2LTEuMDVoMC4wM2MxLjA0LDAsMS45OSwwLjU3LDIuNDgsMS40OGMwLjQzLTAuOSwxLjMzLTEuNDgsMi4zMi0xLjQ5YzEuNTQsMCwyLjc5LDEuMTksMi43NiwyLjY1TDM0LjM2LDEzLjU5eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik04MC4zMiwxMi45N2wtMC4wNy0wLjEyTDc4LjM4LDEwbDEuODUtMi44MWMwLjQyLTAuNjQsMC4yNS0xLjQ5LTAuMzktMS45MmMtMC4wMS0wLjAxLTAuMDItMC4wMS0wLjAzLTAuMDJjLTAuMjItMC4xNC0wLjQ4LTAuMjEtMC43NC0wLjIxaC0xLjUzYy0wLjUzLDAtMS4wMywwLjI4LTEuMywwLjc0bC0wLjMyLDAuNTNsLTAuMzItMC41M2MtMC4yOC0wLjQ2LTAuNzctMC43NC0xLjMxLTAuNzRoLTEuNTNjLTAuNTcsMC0xLjA4LDAuMzUtMS4yOSwwLjg4Yy0yLjA5LTEuNTgtNS4wMy0xLjQtNi45MSwwLjQzYy0wLjMzLDAuMzItMC42MiwwLjY5LTAuODUsMS4wOWMtMC44NS0xLjU1LTIuNDUtMi42LTQuMjgtMi42Yy0wLjQ4LDAtMC45NiwwLjA3LTEuNDEsMC4yMlYzLjM3YzAtMC43OC0wLjYzLTEuNDEtMS40LTEuNDFoLTEuMzNjLTAuNzcsMC0xLjQsMC42My0xLjQsMS40djMuNTdjLTAuOS0xLjMtMi4zOC0yLjA4LTMuOTctMi4wOWMtMC43LDAtMS4zOSwwLjE1LTIuMDIsMC40NWMtMC4yMy0wLjE2LTAuNTEtMC4yNS0wLjgtMC4yNWgtMS4zM2MtMC40MywwLTAuODMsMC4yLTEuMSwwLjUzYy0wLjAyLTAuMDMtMC4wNC0wLjA1LTAuMDctMC4wOGMtMC4yNy0wLjI5LTAuNjUtMC40NS0xLjA0LTAuNDVoLTEuMzJjLTAuMjksMC0wLjU3LDAuMDktMC44LDAuMjVDNDAuOCw1LDQwLjEyLDQuODUsMzkuNDIsNC44NWMtMS43NCwwLTMuMjcsMC45NS00LjE2LDIuMzhjLTAuMTktMC40NC0wLjQ2LTAuODUtMC43OS0xLjE5Yy0wLjc2LTAuNzctMS44LTEuMTktMi44OC0xLjE5aC0wLjAxYy0wLjg1LDAuMDEtMS42NywwLjMxLTIuMzQsMC44NGMtMC43LTAuNTQtMS41Ni0wLjg0LTIuNDUtMC44NGgtMC4wM2MtMC4yOCwwLTAuNTUsMC4wMy0wLjgyLDAuMWMtMC4yNywwLjA2LTAuNTMsMC4xNS0wLjc4LDAuMjdjLTAuMi0wLjExLTAuNDMtMC4xNy0wLjY3LTAuMTdoLTEuMzNjLTAuNzgsMC0xLjQsMC42My0xLjQsMS40djcuMTRjMCwwLjc4LDAuNjMsMS40LDEuNCwxLjRoMS4zM2MwLjc4LDAsMS40MS0wLjYzLDEuNDEtMS40MWMwLDAsMCwwLDAsMFY5LjM1YzAuMDMtMC4zNCwwLjIyLTAuNTYsMC4zNC0wLjU2YzAuMTcsMCwwLjM2LDAuMTcsMC4zNiwwLjQ1djQuMzVjMCwwLjc4LDAuNjMsMS40LDEuNCwxLjRoMS4zNGMwLjc4LDAsMS40LTAuNjMsMS40LTEuNGwtMC4wMS00LjM1YzAuMDYtMC4zLDAuMjQtMC40NSwwLjMzLTAuNDVjMC4xNywwLDAuMzYsMC4xNywwLjM2LDAuNDV2NC4zNWMwLDAuNzgsMC42MywxLjQsMS40LDEuNGgxLjM0YzAuNzgsMCwxLjQtMC42MywxLjQtMS40di0wLjM2YzAuOTEsMS4yMywyLjM0LDEuOTYsMy44NywxLjk2YzAuNywwLDEuMzktMC4xNSwyLjAyLTAuNDVjMC4yMywwLjE2LDAuNTEsMC4yNSwwLjgsMC4yNWgxLjMyYzAuMjksMCwwLjU3LTAuMDksMC44LTAuMjV2MS45MWMwLDAuNzgsMC42MywxLjQsMS40LDEuNGgxLjMzYzAuNzgsMCwxLjQtMC42MywxLjQtMS40di0xLjY5YzAuNDYsMC4xNCwwLjk0LDAuMjIsMS40MiwwLjIxYzEuNjIsMCwzLjA3LTAuODMsMy45Ny0yLjF2MC41YzAsMC43OCwwLjYzLDEuNCwxLjQsMS40aDEuMzNjMC4yOSwwLDAuNTctMC4wOSwwLjgtMC4yNWMwLjYzLDAuMywxLjMyLDAuNDUsMi4wMiwwLjQ1YzEuODMsMCwzLjQzLTEuMDUsNC4yOC0yLjZjMS40NywyLjUyLDQuNzEsMy4zNiw3LjIyLDEuODljMC4xNy0wLjEsMC4zNC0wLjIxLDAuNS0wLjM0YzAuMjEsMC41MiwwLjcyLDAuODcsMS4yOSwwLjg2aDEuNTNjMC41MywwLDEuMDMtMC4yOCwxLjMtMC43NGwwLjM1LTAuNThsMC4zNSwwLjU4YzAuMjgsMC40NiwwLjc3LDAuNzQsMS4zMSwwLjc0aDEuNTJjMC43NywwLDEuMzktMC42MywxLjM4LTEuMzlDODAuNDcsMTMuMzgsODAuNDIsMTMuMTcsODAuMzIsMTIuOTdMODAuMzIsMTIuOTd6IE0zNC4xNSwxMy44MWgtMS4zNGMtMC4xMiwwLTAuMjItMC4xLTAuMjItMC4yMlY5LjI0YzAtMC45My0wLjctMS42My0xLjU0LTEuNjNjLTAuNzYsMC0xLjM5LDAuNjctMS41MSwxLjU0bDAuMDEsNC40NGMwLDAuMTItMC4xLDAuMjItMC4yMiwwLjIyaC0xLjM0Yy0wLjEyLDAtMC4yMi0wLjEtMC4yMi0wLjIyVjkuMjRjMC0wLjkzLTAuNy0xLjYzLTEuNTQtMS42M2MtMC44MSwwLTEuNDcsMC43NS0xLjUyLDEuNzF2NC4yN2MwLDAuMTItMC4xLDAuMjItMC4yMiwwLjIyaC0xLjMzYy0wLjEyLDAtMC4yMi0wLjEtMC4yMi0wLjIyVjYuNDRjMC4wMS0wLjEyLDAuMS0wLjIxLDAuMjItMC4yMWgxLjMzYzAuMTIsMCwwLjIxLDAuMSwwLjIyLDAuMjF2MC42M2MwLjQ4LTAuNjUsMS4yNC0xLjA0LDIuMDYtMS4wNWgwLjAzYzEuMDQsMCwxLjk5LDAuNTcsMi40OCwxLjQ4YzAuNDMtMC45LDEuMzMtMS40OCwyLjMyLTEuNDljMS41NCwwLDIuNzksMS4xOSwyLjc2LDIuNjVsMC4wMSw0LjkxQzM0LjM3LDEzLjcsMzQuMjcsMTMuOCwzNC4xNSwxMy44MUMzNC4xNSwxMy44MSwzNC4xNSwxMy44MSwzNC4xNSwxMy44MXogTTQzLjc4LDEzLjU5YzAsMC4xMi0wLjEsMC4yMi0wLjIyLDAuMjJoLTEuMzNjLTAuMTIsMC0wLjIyLTAuMS0wLjIyLTAuMjJ2LTAuNzFDNDEuMzQsMTMuNiw0MC40LDE0LDM5LjQyLDE0Yy0yLjA3LDAtMy43NS0xLjc4LTMuNzUtMy45OXMxLjY5LTMuOTksMy43NS0zLjk5YzAuOTgsMCwxLjkyLDAuNDEsMi42LDEuMTJ2LTAuN2MwLTAuMTIsMC4xLTAuMjIsMC4yMi0wLjIyaDEuMzNjMC4xMS0wLjAxLDAuMjEsMC4wOCwwLjIyLDAuMmMwLDAuMDEsMCwwLjAxLDAsMC4wMlYxMy41OXogTTQ5LjkxLDE0Yy0wLjk4LDAtMS45Mi0wLjQxLTIuNi0xLjEydjMuNzhjMCwwLjEyLTAuMSwwLjIyLTAuMjIsMC4yMmgtMS4zM2MtMC4xMiwwLTAuMjItMC4xLTAuMjItMC4yMlY2LjQ1YzAtMC4xMiwwLjEtMC4yMSwwLjIyLTAuMjFoMS4zM2MwLjEyLDAsMC4yMiwwLjEsMC4yMiwwLjIydjAuN2MwLjY4LTAuNzIsMS42Mi0xLjEyLDIuNi0xLjEyYzIuMDcsMCwzLjc1LDEuNzcsMy43NSwzLjk4UzUxLjk4LDE0LDQ5LjkxLDE0eiBNNjMuMDksMTAuODdDNjIuNzIsMTIuNjUsNjEuMjIsMTQsNTkuNDMsMTRjLTAuOTgsMC0xLjkyLTAuNDEtMi42LTEuMTJ2MC43YzAsMC4xMi0wLjEsMC4yMi0wLjIyLDAuMjJoLTEuMzNjLTAuMTIsMC0wLjIyLTAuMS0wLjIyLTAuMjJWMy4zN2MwLTAuMTIsMC4xLTAuMjIsMC4yMi0wLjIyaDEuMzNjMC4xMiwwLDAuMjIsMC4xLDAuMjIsMC4yMnYzLjc4YzAuNjgtMC43MSwxLjYyLTEuMTIsMi42LTEuMTFjMS43OSwwLDMuMjksMS4zMywzLjY2LDMuMTJDNjMuMjEsOS43Myw2My4yMSwxMC4zMSw2My4wOSwxMC44N0w2My4wOSwxMC44N0w2My4wOSwxMC44N3ogTTY4LjI2LDE0LjAxYy0xLjksMC4wMS0zLjU1LTEuMjktMy45Ny0zLjE0Yy0wLjEyLTAuNTYtMC4xMi0xLjEzLDAtMS42OWMwLjQyLTEuODUsMi4wNy0zLjE1LDMuOTctMy4xNGMyLjI1LDAsNC4wNiwxLjc4LDQuMDYsMy45OVM3MC41LDE0LjAxLDY4LjI2LDE0LjAxTDY4LjI2LDE0LjAxeiBNNzkuMDksMTMuODFoLTEuNTNjLTAuMTIsMC0wLjIzLTAuMDYtMC4yOS0wLjE2bC0xLjM3LTIuMjhsLTEuMzcsMi4yOGMtMC4wNiwwLjEtMC4xNywwLjE2LTAuMjksMC4xNmgtMS41M2MtMC4wNCwwLTAuMDgtMC4wMS0wLjExLTAuMDNjLTAuMDktMC4wNi0wLjEyLTAuMTgtMC4wNi0wLjI3YzAsMCwwLDAsMCwwbDIuMzEtMy41bC0yLjI4LTMuNDdjLTAuMDItMC4wMy0wLjAzLTAuMDctMC4wMy0wLjExYzAtMC4xMSwwLjA5LTAuMiwwLjItMC4yaDEuNTNjMC4xMiwwLDAuMjMsMC4wNiwwLjI5LDAuMTZsMS4zNCwyLjI1bDEuMzQtMi4yNWMwLjA2LTAuMSwwLjE3LTAuMTYsMC4yOS0wLjE2aDEuNTNjMC4wNCwwLDAuMDgsMC4wMSwwLjExLDAuMDNjMC4wOSwwLjA2LDAuMTIsMC4xOCwwLjA2LDAuMjdjMCwwLDAsMCwwLDBMNzYuOTYsMTBsMi4zMSwzLjVjMC4wMiwwLjAzLDAuMDMsMC4wNywwLjAzLDAuMTFDNzkuMjksMTMuNzIsNzkuMiwxMy44MSw3OS4wOSwxMy44MUM3OS4wOSwxMy44MSw3OS4wOSwxMy44MSw3OS4wOSwxMy44MUw3OS4wOSwxMy44MXoiLz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTAsMS4yMWMtNC44NywwLTguODEsMy45NS04LjgxLDguODFzMy45NSw4LjgxLDguODEsOC44MXM4LjgxLTMuOTUsOC44MS04LjgxQzE4LjgxLDUuMTUsMTQuODcsMS4yMSwxMCwxLjIxeiBNMTQuMTgsMTIuMTljLTEuODQsMS44NC00LjU1LDIuMi02LjM4LDIuMmMtMC42NywwLTEuMzQtMC4wNS0yLTAuMTVjMCwwLTAuOTctNS4zNywyLjA0LTguMzljMC43OS0wLjc5LDEuODYtMS4yMiwyLjk4LTEuMjJjMS4yMSwwLDIuMzcsMC40OSwzLjIzLDEuMzVDMTUuOCw3LjczLDE1Ljg1LDEwLjUsMTQuMTgsMTIuMTl6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTEwLDAuMDJjLTUuNTIsMC0xMCw0LjQ4LTEwLDEwczQuNDgsMTAsMTAsMTBzMTAtNC40OCwxMC0xMEMxOS45OSw0LjUsMTUuNTIsMC4wMiwxMCwwLjAyeiBNMTAsMTguODNjLTQuODcsMC04LjgxLTMuOTUtOC44MS04LjgxUzUuMTMsMS4yLDEwLDEuMnM4LjgxLDMuOTUsOC44MSw4LjgxQzE4LjgxLDE0Ljg5LDE0Ljg3LDE4LjgzLDEwLDE4LjgzeiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xNC4wNCw1Ljk4Yy0xLjc1LTEuNzUtNC41My0xLjgxLTYuMi0wLjE0QzQuODMsOC44Niw1LjgsMTQuMjMsNS44LDE0LjIzczUuMzcsMC45Nyw4LjM5LTIuMDRDMTUuODUsMTAuNSwxNS44LDcuNzMsMTQuMDQsNS45OHogTTExLjg4LDkuODdsLTAuODcsMS43OGwtMC44Ni0xLjc4TDguMzgsOS4wMWwxLjc3LTAuODZsMC44Ni0xLjc4bDAuODcsMS43OGwxLjc3LDAuODZMMTEuODgsOS44N3oiLz48cG9seWdvbiBjbGFzcz0ic3QwIiBwb2ludHM9IjEzLjY1LDkuMDEgMTEuODgsOS44NyAxMS4wMSwxMS42NSAxMC4xNSw5Ljg3IDguMzgsOS4wMSAxMC4xNSw4LjE1IDExLjAxLDYuMzcgMTEuODgsOC4xNSAiLz48L2c+PC9zdmc+"},{"id":"geodata.md.gov-MD_SixInchImagery","name":"MD Latest 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","endDate":"2016-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","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","description":"Six Inch resolution aerial imagery for the State of Maryland"},{"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","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","description":"Maryland State Highway Administration road features and additional Maryland focused landmarks"},{"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","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]]],"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","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABLCAMAAAAf8MQEAAAAAXNSR0IArs4c6QAAAt9QTFRF////q6ytVFplAAAB0owMmWYJRS4EZWx3o6OjYmNl7JoE/agGdE0GBgUA9aQOzIkMKhwCFA0BJBQBNBUAdHV15OXpUlVYGhECkWEJ5ZkOsXYKbkoH/64Qu30LgVYImpqbSTEEa0gG8qIOVTkFEgwBHhQCqnEKMSEE/80So20Kck0HCQYB/7IOMzM0uru+Q0tYRCQA/8ER/9oT/+EUlGMJflUI3ZQN/7kQ/60PaUYGZUMG/7EQ/8oSJhkCil0IOiYDMB8CfH1+yYYM4pcOiFsI2ZIN1Y4N/8URIRYCi4uLa3B5NSQD/74RzooM7qAO/7YQ6+vsiloD+6gP/aoP6p0OrnQLnWkKm2kJWz0FUjYFMSED/9QTjV4JdHZ69ff77J4ODAkBX0AGAAEL+fr7S1BVBQIAtXkLhVkIPikExIMMTjUEFhYXysrLxcXF+qcPwYEM1pENHSIqPSkDLR4Dck0I/qoQRzAEe1MH/+gVWzQAg4SFJCQlelIIDgkBYUEGQiwESElLLSADSi0B/9ESDAIArrS9v4ALTDIEDAwMxsvVklsAHRMBjmAJP0JHAAETdEUAhVcISVRlxoUMd1AI/7sOz9HW1IoChFkHomwK/+UUYj4D96UQZjYAGiQ4OURXg4eMk5mm/6wJwH8M3uHmp3AK/90UNDtJLhQAFxABGQ0Bg1gIglUEJjNJl14FsnMBlmUJ0YcA2drbi5WmFQIAi1MAa2trbHaHW1tck5KS8fL0fEoAOxwAJCw7/7YFUiwAgU0AJQwA6ZcCJy9BDRcrsLCx/8oU2t3j7/H2ChEfu73DAAAA1NXXAAAGWmJtEx42qWoAVDkEzIQAa0YEo2QAAw4lfIGNhY2bdnyIm2QCp6y2eoWXLTA5w34AjZKbRE1hdn+RrHEFxoAAu8DGY26BAQocnZ+kvHkB5JQB/8QOhIqVORcATCYA24wA+6YK8JsCJQYAn6Wu0YsMnai8hY+hU2B4tSvHUAAACMpJREFUWMO1mP9TFPcZx2nfd9do7xutySG3dznuzuOOQ8PCwd65C2eFY69h6ya7CMuXBDRzcNDksOJhUwkYz5IYLFaKDco41qqNEztmnMwk1aaNbZN0MtpYG5O06ZdfajWTpJl2pn9An4WxxS9HhZl+fgBm9/P6fJ7P87yf5/ksBQX/j/E50DAY9Z/4wuLQe+8jxlFYVOwE44LZvRK4fxE0UAJ4jb5VAVtpMIRwuQNYfdf4AxVsFRtBdU00hmJeqEVdHOvwlbvFMTciBpRI+Bo20EEgVzcAd0U/9HAgpMhqzcZwK6CF29pLw52wqc0mPPLoXdD6zqu0Lo5d3yKDQRws6oH1XZuAzY/dheWmysyACSFRllaVJlsAPlMOxB1xxPA/PLDmG/BstUr127IZUzIqbkHNkAN1omzXTdqeRiG+tQC9A0/CJBfpcwetoVR9R6Kp0/dUWuiKAz79aWv+/XfO+jsZ634asK30AKSWGIaJ4HZhDo/kENv9UJ5TN40lakK9ydFamvgMsToPsAPgurdRDPQlWlBU+Owd+T3PiUILbWGvNgHjsPSjv2+EoLJKcP4e3RB91O4FvnMHej84toxeGyabBmwDGN+O70HzFfP0yMbCC4SAUYDWmdp9u34O4PtsDI5Jrvr5Mne1PIyw3eEaD/T1kT1sJQ4msRFwYogM6ANuM39iX/AQDgXZ5JxgOZu/xj+JtK21jk7ct7EqiRkfRsIRwNMP5+Fb6B8cFYubpawv1uCtslVSlsHLS05vO1iWLDY3lg/C20+OYIF2IHOL+ccg8TKbjZaJuaJqOHs6arR6JSqFGFg3TQNlW8rjsJrQDwm9FoycmIv+ih3ACh3/0QucxCckZkCKztoeEiSecEkoMWKMnG7LJuAdRRoyRANkfdKNzNRNxxTsibWIqYzqCoTpYXuQEeowkPG3wwRXW5VpAwKmMFxuFAWRQjc7TdufrmRnrdj8XE4TONYFWZ4k9iXydkDowTQnMZ0mlPKdnMeKuMmPlSrSHTRjYwA49phZrMQZ3Qq2R5YVhn1KDFJ4kNAVMoi1ckYN1rGFEbfEdgv2dE0EouQARy9FoOKBFXAU60X02NEOcw3NVQV6czCTHG94CbBwIqdGpZFOuFGbA59ubx4eFYm14ZEClEntN05e8MoJN+rlDLmKzErANxwv1fOjbEyWZlAMirVs92IwGlo/QMapqVcL8MWDNGHvLH52ohOeRjnDFgPFlXDSU8/W0XEqM8nK7RYh7Ca8uhnJDm+jx5jE6Ln9FKkAUvaD53T8CaDzRE8Hh0ZPMAq+3oxefqMJRoajpG335ygBrblxnAxuiCD94m7fdjxesAbdghdJHV/2c8jBcc0yXtUiaJCmqK4OdoqbMCC6KfMwSllirQFacj1j8KeQntRt3nnoYN/c2Ze9PtrB+4GwVeCc9TwH11DEmFMQiDbDjG46ETZQs1rZ0S7BCL/mmqXO/+JLc5p79s1YM47XFrfqxUhkfWVubHAIAd2xiZawNQuxT49kLob29iJKWnLRbMG+94nH9V+OSbcBdm0wRXNKmnPF6ouUGV3f1PGUrKsgJIdR18UgPBLTO0aVpr01L18KzU4NTc7C7tI2ItLTQoikYTXPxvU4EOwZPlkNC6uhpQso7EXQq/36psrOhtHkKBn0wYO3d+qaonlvXEDWAj/6EqK+zo7XUEa1IDXW6xAaNl38zXxcgik+UtpmxKqKX94DE2ewUkK/E49SW4NdFB06f2a2DDcLZs1VFrv0zs34KLzr0hFYfovVGFYZxoz7cBprSRHoEeM6eXbN/fcgIAvlI/EILuO/3WoZHTUONY3Y8+lEEGAURYnYZYx4U0X4Lorm6tcOPUbANjzdNIKjeGsezrqTiAyhtgpolBElfEuTEKqxj44QN2rpJdXPXg/owvK7cX2td6/Mv8XkfjgUqd1KSUJvZnFV1mSqkW6kZutmrpky8Kbe/948178/xaiiw4zCetP2QjtkJZORIj0Ry0mEbaU011pt6V7obnBJUrkQbgyOZaVgnZX+Mpav6ySbPP9J7TzdbYrhRa3Jjlg1ySzV0BKZJnUHOlnomyvU32Ilnrfz4h9gisVYTSkqu1BtmN2rl0qHik4KhLvDI5QrM9xC2/+exyRrRS8LbWiY6G7VYxwMIkR4WWWTOKOoDB7Mi/8BDZDkLXpLHtyme8EWccOZ8AVyJPtck0ixmLk0sdCVxs7yzRjWW2wf07+3z0ZZ7YGLcEZO8KQERXz5lfz4xGmJb4wX+Xyo9ett3I2v6yHrgka9S9VxaaHtJ96lLicaSTU9VYZG24k/oWD16r+8vAsBSZkb5c0LOO8ClgciHMcxYhqXL5/CH+cer97K6xpmIryiqsG/5udfO+8KScqMKrXiytWrf7ux6jVRt5zr4fSfFxdw3ubGEZuiKswUblGUDgbKyQge+aVTsCc446SdGEH74GZFkd9ln6GcVtl1eAFclHyMzPNad2rzvAVwSlLUzFopS0tfX8B5+1nOx/cG3M8EPzo0b9oeXCeTtGyUlJMfP4Bz/EqXjeMMgotjH56fzuD6tspRNRpVy/F+Pse9LnBBF8sFj7O8N7j8zHzv5VrAz6iGAT748Yd58Cv7xOo6p1RnGJaCYJ+c/+rwiTaQ+6ZbZSEv/m0IljdlH0JO/fr451uu+BGKmllWrl/M/w3xCfYJWuq0Gdd+9cYt6VQoU+wMvPJpfs8f+fyDmz/efceylGI4ync+OlPx48V/TuKnnKpEmSwF7tzEEvCfZenkdQlS3WdYNP0e5BlFifbLC8om7zg7UcHyKlPPqNHs3/GPRfOP4vQ/ZTWqMusZ4csfLv7wB64Osnrf8qjiUvCCf73AKiov+fjMYr/k53x/jVNVmTUW18SxFPwzWcnKnDIsn1oSvlzqoc+FrNzF7l4K/hF9PNazHNtbWbEU/Px1tLjlkYSx45Ol/R+lQpROYoDjtKXhn0qyBQPeNiwNPxeUUFupYYn4q37/ha8eOfKTs7e9+TeLgDxdoqv76wAAAABJRU5ErkJggg==","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","endDate":"2015-05-03T00:00:00.000Z","startDate":"2015-03-29T00:00:00.000Z","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],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-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.466251,39.750764],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-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)","description":"Digital orthophotography of New Jersey, Near Infrared, 1 foot resolution"},{"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","endDate":"2015-05-03T00:00:00.000Z","startDate":"2015-03-29T00:00:00.000Z","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],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-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.466251,39.750764],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-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)","description":"Digital orthophotography of New Jersey, Natural Color, 1 foot resolution"},{"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":[[[-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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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":[[[-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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"id":"NLSC-EMAP5","name":"NLSC General Map with Contour line","type":"tms","template":"http://wmts.nlsc.gov.tw/wmts/EMAP5_OPENDATA/default/EPSG:3857/{zoom}/{y}/{x}","startDate":"2015-01-01T00:00:00.000Z","scaleExtent":[0,15],"polygon":[[[120.4570579,26.3970586],[120.44256,26.3708009],[120.44713,26.3531513],[120.4673009,26.3405831],[120.4978723,26.3340866],[120.5141036,26.3401594],[120.5341168,26.3641649],[120.5297045,26.3842128],[120.4956661,26.4015754],[120.4570579,26.3970586]],[[119.9007221,25.9858609],[119.8960071,25.9648902],[119.9131301,25.9470399],[119.9503542,25.9278478],[119.9905563,25.9260623],[120.0198392,25.9363284],[120.0277804,25.9557423],[120.0275322,25.9845224],[119.9989937,26.0010288],[119.9404278,26.0028131],[119.9007221,25.9858609]],[[122.089,24.5485],[121.709,23.4541],[121.717,22.698],[121.818,21.95],[121.803,21.8735],[121.759,21.8087],[121.694,21.7653],[120.861,21.5631],[120.815,21.5576],[120.739,21.5728],[120.661,21.6296],[120.202,22.1809],[119.27,23.0542],[119.153,23.2049],[119.128,23.2485],[119.103,23.4],[119.118,23.4765],[119.137,23.512],[119.361,23.8885],[119.406,23.9407],[120.968,25.2284],[121.408,25.4687],[121.989,25.8147],[122.065,25.8299],[122.141,25.8147],[122.216,25.7663],[122.26,25.7015],[122.297,25.48],[122.196,24.9696],[122.089,24.5485]],[[116.6855033,20.8547596],[116.6309071,20.8149565],[116.5941695,20.7600846],[116.5797214,20.6967501],[116.5893056,20.6325865],[116.621766,20.5753367],[116.6731874,20.5319171],[116.7373678,20.5075783],[116.8065659,20.5052653],[116.8724354,20.5252581],[116.9270316,20.5651373],[116.9637692,20.6200797],[116.9782173,20.6834462],[116.9686331,20.7475883],[116.9361727,20.8047732],[116.8847512,20.8481147],[116.8205709,20.872399],[116.7513728,20.8747063],[116.6855033,20.8547596]],[[118.2261504,24.4563345],[118.2936439,24.4538527],[118.2851467,24.4751026],[118.3097372,24.4916821],[118.3767709,24.4729348],[118.4100947,24.5332285],[118.4479031,24.5284069],[118.4746394,24.4599272],[118.512992,24.4315479],[118.5065839,24.4202318],[118.4811625,24.4332439],[118.4610567,24.4089192],[118.426145,24.3970385],[118.3970055,24.4284184],[118.3765564,24.4258395],[118.3397565,24.3814628],[118.3031926,24.3705764],[118.2574234,24.4139213],[118.1381276,24.3724838],[118.1617342,24.4022433],[118.2094226,24.4139604],[118.1895784,24.4352201],[118.2176338,24.430205],[118.2261504,24.4563345]],[[120.2234496,26.30045],[120.2550843,26.3100412],[120.269888,26.3368716],[120.2591889,26.3652192],[120.2292544,26.3784823],[120.1976197,26.3688968],[120.182816,26.3420738],[120.1935151,26.3137205],[120.2234496,26.30045]],[[119.4374461,25.0047541],[119.4342024,24.9886249],[119.4541901,24.9722553],[119.4827444,24.9718376],[119.4898402,24.9937882],[119.4715877,25.0069239],[119.4374461,25.0047541]],[[119.8869914,26.180381],[119.893227,26.1203128],[119.9285109,26.1080224],[119.9779388,26.1223611],[120.0366775,26.151728],[120.1098054,26.2134921],[120.119269,26.2713663],[120.0629175,26.3172592],[119.9923706,26.3164881],[119.9467732,26.2898799],[119.9020362,26.2439761],[119.8869914,26.180381]]],"terms_url":"http://maps.nlsc.gov.tw/","terms_text":"© National Land Surveying and Mapping Center, Taiwan OGDL 1.0","description":"The emap from Taiwan National Land Surveying and Mapping Center","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABHNCSVQICAgIfAhkiAAAAxJJREFUOI3tlF9oW2UYxn9f4nKW2ixfjJGYMnuctRUZ5mhEpjdJEEaHtmsZaKHq0qt6ZdtZL3Zhk3ilIKS9Ui806UStE7Edjln8kwzEwaB6IshsmJIqK1ttZ7Qlzel2eryQhqZrsDC8EHyuvu993+/53j+8D/yPfxtip4GqH1X1owLkdHI3RSwbkbFu1yAPdx4t3hpSS6YLAM05i/vCqcmzZwpj9T6pIZYOZNArNADhsQj3RVNjtyS1DcKtiHlPIb96PTn67nJiq8++cRgJicTpQ7Yz0oHc7cQZeakzPbTyqr9iKXUr0lfbqOx7LHJgbXrux5/X9M0+G0C8SySeeWTPQPSLxu4jn1vd4tE7m4euDNclrCEvt6E+25/e6H+VuKen57vEe1b8I29b8cKyo6j6Uece6I/VK387jC70crgjMFBDPDEx8aA5aOPkG+f7FhcX9YhGZLIUBSD7VAtSsZOKNpGKNgFU710tbiJ7G0lFm9DucCL2R7uCXjTpQFZbMV6wMu+EbWnpQOIJVKcvFTuDIR+az4nmc1Zt6h4HuV9XGHjIx1D2EvrCKtLnUgE+Pig+kQ6kDeDFc9YQwJdP2rLuBlfzRjklw7yh7JJh0vfZL6Tb70IqdqRSnT/5JfQTBcZfDom4HaBiUjn5k/Xh0VYRe85ztZ11QX53K4ZQyPxwFcO0yP+2Ste9bi6XrxPbfxuvnV9g6uIfPK/dTskwURbOFfPTM2PSIeTT99Bzw4KMhERi5ICIl667OOHuYNzdQV5p/ccBxi89kUmm5vveDou06kLddvNSibasbvZGXvj9fYJGgbldAaYaI+SVVoq7ApxtCNXEH7ZyhL8+Nho00YJeoT3+6Xp0W2KtBU07NpzNlHulem2ecHmGzpUcmlGg+dp83aynitbkK99ayfwSel2tiLUTo3M4lSn3ys12ub5MsFL4O4GGWZq/fyszfvrPsfwSNZtnpw70i+jMfjPdf//MfXf7UYtrASqWQkUoeNzLtHumS0buzePJD4zjV1a5vPX9jmRT9aNGNCKbZXMn0vnfwl+e9BTflqrxKAAAAABJRU5ErkJggg=="},{"id":"MAPNIK","name":"OpenStreetMap (Standard)","type":"tms","template":"https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png","scaleExtent":[0,19],"terms_url":"https://www.openstreetmap.org/","terms_text":"© OpenStreetMap contributors, CC-BY-SA","default":true,"description":"The default OpenStreetMap layer.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAGb0lEQVR4Xq3MS2xcVx3H8e855z7m3vH1jMdjO43zshIrtpM0SZ3WFEcRVFFKoRWPBYtAHwgWCFUsQN100QeCsqAhCESrirRASdWWIkoUqgKFJm3UZ5o2oW2akrR5uXbi2ON4PPfOfZ17iERW2bCAz1/f3V8/cfDC02UEj4OxKHjdFMUfmUzOlAeXZFZuuVIKN8zi1dPh7Hcn5091G2EOB5b//NplA28/9tAT4bq111jD64ZKHR2VQWPEbULI0aHqZz7NZeLNmSeVMOJu4AfGgNEGLsR/95YuetcRzprcFJvaaVxrpm2mmqfp8FxKSYk8ck+0pt1nykFp0A/k9Tnt/lq3T2dHEOmi2DxSu+EdAAFwcPqp640xe42h26Qa2hqnXsFVHs04pNFuYgvbtOWCmD3aMj2VNaLi1+jwyxgpCKOQRCdMN6ZMd5Bmw1cPfG+5O/7LeX0ECyBppx9Zrn0c6BbNHJNr4qhFYWtsJCWpSFUm3ntxips2bxe+p1BKIJQECpRbkCQ2wu0XzbnIeemvhzYCVNR6JMDm5bdNF9qcwhiKbpvMg2KujZDmUgX1jgqT719gy+iX6QxsPM9F2YqclHbRRpUEXmCRZTGFlZGKxSMbR6+uA0gu863OzLc7cVUZN6jgKI8kicl0ykzjAiW5lGrVAWUwokApSa3UTY/XR2B3UlDgVy1sB8od7tgt2++4AcACOHL+uRW2bW8QQiCxcUoS6XssyBbnF6Y5+8kci8vjlJwqjnQwWpDlgtRYZDpHmxJzWUyk26gOYXxK0g+8G4bXX/snC0DZcmVh9EoQ5DpDSIVJYmIiGvkCurAQpkLU9kkTEEJeCjxbURSCZgTkfVjOApoM6Qtc3109Nj7uWO9M70EbPQT4YMhNjrWQEdHmTPs8SgfUisUgDLoAgcGyEjJtEaeaVlKQ5gVSGYwBhETaEmVJcemQaZ44aRpvyLIEnedGoNHNkNTTeI5DT2kRljeJziVhnKNlE1GaJFfnuRi3SXMDxmA7IUqCI20qdifkxfED+/dlanzb1cYL3BFhsTXPU4Ep0FGKUVALegCb1oLN7FlNpd5HIUNQLYxIsO0EKcByWljuAmXbp7fcIwgVb7xyaNeep3YfUnt272PLjaP1em/lZqmEk4cJQoMKfBxVIcwjlAp47okX6ap3XaoP221CIREyx7La2E6O7/h0eTXK+Bw+8uHrP7znvocXLe6flwCHXj06kab5hJAS6dhQFOgiJ2qXsKLVuHqAgdVD7HrwXibPTKJzFyMMAgECHGXTJTqxE4t3T5xMD7y29+mFRjgpLSUlYJ793T9ORWF0Lk1StCzQNqTTAle30flbzJ/bx6n3Xsa2Fb9/5Eccfu19wnlNFBniWJA3JecbDfa/8y5nJg7bW7ZeuyYKZwyF0QIAkC988Ogzfof6SppapHGZqgNTExPsfngfgaXpqyWk9QF6lwWk7YJlK1fQaTysqk8sE6LwIq4OEMql1DH3/O03PnBHUCk3JMCeA7/q6u1a0ltiNZ1eL719cPrcWR752d+Yn2lx/HSDY40qY2Pb2PapjYxv3YBX1syZ88weP3bp90Omw3PMOxNUe9FTn9gn5uemQqfk5BbAisHBlVo7g7PFx9TdgDMnZvjtzheI51qkWY5xYWxTLxXfJ5IVevIZ6gMDxCYnPjWDXZ0nSiOkEmYqO5l8cGT6FSD6+NhRJMCF1sWV88VkX6f3n/FHd+xl9uwsrTDEOIbPfWEj120eorw0JEzLhGWfop3ixxKrP0CTIQSAEVmhw5/f94uXAANg3b/r+1YrnV1T86ucPDzBrp3PcvHcHGmaUekL+OKtm9m0ailOUEe4FrXyWaKFblM4HmUvElNzF4jTxFiOhRRSJO34JHCOy6RU0i60uepfx07nO+593FycapAkCbX+Kl+/cxvXfXYIU3GjN/Yf2vPPg2/9JVxoNYNqQ+hcilznlKWDcpSwlCWiZrtx/O3Tf+AKClj88I9v/9aD99/aHBkaLlYNDTXuvPubH/3kN3e9vP3bn78HGAP6gSXA6K3fufnOXz+/888vHH3i9O4XH3j1roe+8dDo1pGvAeuAClfa/+aTQH35Yztuenz7l4aPLB9c81O/3H3L5VHFlUACZaAH6AQc/pv1o9cEiwbWbRlev+mrazeOblg3usnj/6nWV2fVyFp71fCa0sDgkOKyq5av4H/xb0Ky8po5hQEuAAAAAElFTkSuQmCC"},{"id":"OpenStreetMap-turistautak","name":"OpenStreetMap (turistautak)","type":"tms","template":"http://{switch:h,i,j}.tile.openstreetmap.hu/turistautak/{zoom}/{x}/{y}.png","scaleExtent":[0,18],"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":"https://www.openstreetmap.org/","terms_text":"© OpenStreetMap contributors"},{"id":"osm-gps","name":"OpenStreetMap GPS traces","type":"tms","template":"https://{switch:a,b,c}.gps-tile.openstreetmap.org/lines/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"terms_url":"https://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;'>&larr;</span> <span style='color: #96f;'>&darr;</span> <span style='color: #6e0;'>&uarr;</span> <span style='color: #f63;'>&rarr;</span> </span></span> © <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>.","description":"Public GPS traces uploaded to OpenStreetMap.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAGb0lEQVR4Xq3MS2xcVx3H8e855z7m3vH1jMdjO43zshIrtpM0SZ3WFEcRVFFKoRWPBYtAHwgWCFUsQN100QeCsqAhCESrirRASdWWIkoUqgKFJm3UZ5o2oW2akrR5uXbi2ON4PPfOfZ17iERW2bCAz1/f3V8/cfDC02UEj4OxKHjdFMUfmUzOlAeXZFZuuVIKN8zi1dPh7Hcn5091G2EOB5b//NplA28/9tAT4bq111jD64ZKHR2VQWPEbULI0aHqZz7NZeLNmSeVMOJu4AfGgNEGLsR/95YuetcRzprcFJvaaVxrpm2mmqfp8FxKSYk8ck+0pt1nykFp0A/k9Tnt/lq3T2dHEOmi2DxSu+EdAAFwcPqp640xe42h26Qa2hqnXsFVHs04pNFuYgvbtOWCmD3aMj2VNaLi1+jwyxgpCKOQRCdMN6ZMd5Bmw1cPfG+5O/7LeX0ECyBppx9Zrn0c6BbNHJNr4qhFYWtsJCWpSFUm3ntxips2bxe+p1BKIJQECpRbkCQ2wu0XzbnIeemvhzYCVNR6JMDm5bdNF9qcwhiKbpvMg2KujZDmUgX1jgqT719gy+iX6QxsPM9F2YqclHbRRpUEXmCRZTGFlZGKxSMbR6+uA0gu863OzLc7cVUZN6jgKI8kicl0ykzjAiW5lGrVAWUwokApSa3UTY/XR2B3UlDgVy1sB8od7tgt2++4AcACOHL+uRW2bW8QQiCxcUoS6XssyBbnF6Y5+8kci8vjlJwqjnQwWpDlgtRYZDpHmxJzWUyk26gOYXxK0g+8G4bXX/snC0DZcmVh9EoQ5DpDSIVJYmIiGvkCurAQpkLU9kkTEEJeCjxbURSCZgTkfVjOApoM6Qtc3109Nj7uWO9M70EbPQT4YMhNjrWQEdHmTPs8SgfUisUgDLoAgcGyEjJtEaeaVlKQ5gVSGYwBhETaEmVJcemQaZ44aRpvyLIEnedGoNHNkNTTeI5DT2kRljeJziVhnKNlE1GaJFfnuRi3SXMDxmA7IUqCI20qdifkxfED+/dlanzb1cYL3BFhsTXPU4Ep0FGKUVALegCb1oLN7FlNpd5HIUNQLYxIsO0EKcByWljuAmXbp7fcIwgVb7xyaNeep3YfUnt272PLjaP1em/lZqmEk4cJQoMKfBxVIcwjlAp47okX6ap3XaoP221CIREyx7La2E6O7/h0eTXK+Bw+8uHrP7znvocXLe6flwCHXj06kab5hJAS6dhQFOgiJ2qXsKLVuHqAgdVD7HrwXibPTKJzFyMMAgECHGXTJTqxE4t3T5xMD7y29+mFRjgpLSUlYJ793T9ORWF0Lk1StCzQNqTTAle30flbzJ/bx6n3Xsa2Fb9/5Eccfu19wnlNFBniWJA3JecbDfa/8y5nJg7bW7ZeuyYKZwyF0QIAkC988Ogzfof6SppapHGZqgNTExPsfngfgaXpqyWk9QF6lwWk7YJlK1fQaTysqk8sE6LwIq4OEMql1DH3/O03PnBHUCk3JMCeA7/q6u1a0ltiNZ1eL719cPrcWR752d+Yn2lx/HSDY40qY2Pb2PapjYxv3YBX1syZ88weP3bp90Omw3PMOxNUe9FTn9gn5uemQqfk5BbAisHBlVo7g7PFx9TdgDMnZvjtzheI51qkWY5xYWxTLxXfJ5IVevIZ6gMDxCYnPjWDXZ0nSiOkEmYqO5l8cGT6FSD6+NhRJMCF1sWV88VkX6f3n/FHd+xl9uwsrTDEOIbPfWEj120eorw0JEzLhGWfop3ixxKrP0CTIQSAEVmhw5/f94uXAANg3b/r+1YrnV1T86ucPDzBrp3PcvHcHGmaUekL+OKtm9m0ailOUEe4FrXyWaKFblM4HmUvElNzF4jTxFiOhRRSJO34JHCOy6RU0i60uepfx07nO+593FycapAkCbX+Kl+/cxvXfXYIU3GjN/Yf2vPPg2/9JVxoNYNqQ+hcilznlKWDcpSwlCWiZrtx/O3Tf+AKClj88I9v/9aD99/aHBkaLlYNDTXuvPubH/3kN3e9vP3bn78HGAP6gSXA6K3fufnOXz+/888vHH3i9O4XH3j1roe+8dDo1pGvAeuAClfa/+aTQH35Yztuenz7l4aPLB9c81O/3H3L5VHFlUACZaAH6AQc/pv1o9cEiwbWbRlev+mrazeOblg3usnj/6nWV2fVyFp71fCa0sDgkOKyq5av4H/xb0Ky8po5hQEuAAAAAElFTkSuQmCC","overlay":true},{"id":"lu.geoportail.opendata.ortho2010","name":"Ortho 2010 geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2010/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","endDate":"2010-07-02T00:00:00.000Z","startDate":"2010-06-24T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"id":"lu.geoportail.opendata.ortho2013","name":"Ortho 2013 geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2013/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","endDate":"2013-07-20T00:00:00.000Z","startDate":"2013-07-19T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"id":"lu.geoportail.opendata.ortho2016","name":"Ortho 2016 geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2016/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","endDate":"2016-08-16T00:00:00.000Z","startDate":"2013-08-30T00:00:00.000Z","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,"icon":"https://www.geoportail.lu/static/img/lion.png"},{"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":[[[-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]]]},{"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 (Philippines 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":"Actueel_ortho25_WMTS","name":"PDOK Luchtfoto Beeldmateriaal 25cm","type":"tms","template":"http://geodata.nationaalgeoregister.nl/luchtfoto/wmts?FORMAT=image/jpeg&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=2016_ortho25&STYLE=&FORMAT=image/jpeg&tileMatrixSet=OGC:1.0:GoogleMapsCompatible&tileMatrix={zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,18],"polygon":[[[3.1437689,51.3598403],[3.1575018,51.2411346],[3.3387762,51.1154412],[3.9128119,51.0585083],[4.6571356,51.2806657],[4.8933416,51.2634825],[5.1789862,51.1257851],[5.3849798,51.1309561],[5.5442816,51.056782],[5.4206854,50.8595581],[5.4673773,50.7032633],[5.6568914,50.6192567],[6.1485296,50.6214349],[6.3023382,50.8578243],[6.2995916,50.9543819],[6.2638861,51.0183545],[6.3723761,51.0925902],[6.4012152,51.2011393],[6.3737494,51.2510206],[6.4451605,51.3158713],[6.4204413,51.5496009],[6.343537,51.6792182],[6.796723,51.7642909],[7.046662,51.9102418],[7.0713812,52.0455856],[7.2718817,52.1704147],[7.3075872,52.3855111],[7.2059637,52.5319494],[7.282868,52.614576],[7.2993475,52.7785318],[7.4421698,52.9782705],[7.43393,53.2831352],[7.0439154,53.5515877],[6.7829901,53.6363531],[6.2391668,53.5401639],[5.6871039,53.5124077],[5.173493,53.4388477],[4.8164373,53.2338445],[4.6516424,53.0658312],[4.5417791,52.4859784],[4.3220526,52.1956753],[4.08104,52.0136897],[4.0219885,52.0162253],[3.9368445,51.9637937],[3.9519507,51.8807927],[3.844834,51.8494157],[3.6237341,51.7075226],[3.6553198,51.6606936],[3.6333471,51.6274583],[3.5468298,51.622343],[3.3957678,51.5609145],[3.3820349,51.5173524],[3.4987646,51.4326715],[3.3298498,51.3855587],[3.1437689,51.3598403]]],"terms_url":"http://www.nationaalgeoregister.nl/geonetwork/srv/dut/catalog.search#/search?facet.q=license%2FCC-BY&isChild=%27false%27&resultType=details&any_OR_title_OR_keyword=luchtfoto&fast=index&_content_type=json&from=1&to=20&sortBy=relevance","terms_text":"Kadaster / Beeldmateriaal.nl, CC BY 4.0","best":true,"description":"Landsdekkende dataset 25cm resolutie kleuren luchtfotos van de meest recente jaargang.","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABpCAMAAAD/V6aFAAABQVBMVEVHcEzFxcUIjtE3quLGxsYMlNMxseXFxcXFxcXGxsY3qeC82+c4qeA4quEcod3FxcXGxsbGxsbKysrHx8cGkdLGxsYPl9fExMTGxsbGxsbGxsYGjtDGxsYLlNXFxcXKysrGxsY3qeDFxcXGxsbFxcXGxsY3qeHGxsbIyMjGxsbGxsbFxcXFxcXFxcXGxsYBi883quHExMTGxsbGxsYgpdkYntoeqtXGxsYko93FxcXFxcUio97GxsYDjdAcn9rGxsbGxsbGxsYQmdjGxsYCjdAAis0IktM1qODGxsbHx8fGxsY3quHFxcUco93GxsbGxsbFxcUmotw3q+E4quE3quE3quACjtEKl9XGxsbFxcUZoNkBi883qeHGxsYAis44quEAic0AiM08rOIcnNk6q+IspN4Mk9QFj9EXmdclodzGxsbX17u1AAAAXnRSTlMA7d4ItK8KTHw//QHerC31nSgFHsszjQ5Bw23d6qMYFFmUZtVH78rkCTn4uIZUdvqAFKxPDUAEozao2iLQ5V39lLF/y+z+wd1he76y+hGNgC1uQO7BUNR6mYRR96TdoavfmwAABLhJREFUeF7s08Fqg0AQBuApCC0IBBtCYpBVbMQmNoF4CfGykV5aKKbXAn2B//0foOLspQF0xhQokO80/2l2WH66xnNx18vz6S+c0K+ha8TukQn62RWNFxzfeY2J0K96pLH2zSSf81hjwIHGevsG7nncYkhC45gDgNKdlWOA/Uo7MemsnwBkAYcGQtmcVJINWi8cZhZCR1JZWrSiKacSUkvSeEBnx2llIWQ/Vbegk8UcQ0i9asqTgJ05biF2Jrn1BJ2J0R6DKmzJGmSq371eWOgsSKK8+M4COrmoOimckHPwAR2PBPbRRQUaKKU0zK/hRHy72UDHTmmYqT1nx2tnhadz8ulfuLn5YazseRMEwjhuJDCIOhkXw8DiagchJkQGInZoHKxWk7Y5nkO09ft/gTb3Sjg4nt/4T7jf5XnhIlcR8SRzbUxaeO/XBFQCGxasd7QToLeyMBglvZZ4AUSw9VjyCcTCvTI1Z0TNciIAlydziwZ+ihZe+jUZVUekPNlbNPS3LEwQrXHVoblozdZas7KqmmU7rXstjm7N7sCSaW7TPO//yM4vOYiaJV9EADOfJUcgVoDK/ix9/NaQ5gQEQOzQh+hPOECTgdJkLPBnfRoQqzPa4DUBJZLImAD76ow9vEZP7yrhzVr11kxM2gTr0HfXgxa1t12jVucDr5mqu8MlZkkKLZbHrYao2eg7DEOkSh8Ke55c2zTPskZRI0VOgNYEMulqukl1SlAWb6s1884/GjyKDt4GKDY5UVxZEl9MjXhjTKojTjOnIKGpfNPAQNTMBLegzn4xVPBPDrNhk8XwddzOGbeg/trT+DxyPAOni/ivXfNbbRSIwvgpLCQiYIyIRmAT1hS1RCEJICmCgjdtKKmXe+ML+P4PsCmzG6Y96zczFO/yu3WGzxnPmTl/JCV37gTFXKb4m6e9zk2JQPWBp5cirfMHY1YoJOi+5MqOkHFrY5kXoLL8WsV4c4XMk6lK7QKZiI326QPPMZWJwafx+UtnojL8aCqzAFZWDYyjeJIYbdgVUIkuB04hvllsoJL4bueO79kclOFbA5mSEHkN5hwMZI4ECP9vs2fx9F1fxfGQX47YUiyc+UVfprWBSjIw5OLTVl/mAlT6QYYfA12NDDhZSLhIZRThAOuHAfBKOviJss5rx98ubGfwTQ+gZ2PSFdriY7EShrMDiyn12hmQx71wK3i1qLCjQUWmKqc6P9UyVmhhwrUYmI0NDH0C3LnjzTTZCicPjnhYh+NLNZbofyiim4IYZi2fnU733hm5ACrT0A5fbSti6AQryWm++9HXUhCRPquXzDnABWwCupJ20VlcBsq4Y0YM5aRyTzfC07+uUlcrD3KOpR01hGexI/ZI1/Nhk+cWjbBsoYqMbYm77TjWSkcpU24cnKYJCDMNl7NKaZR3YO8oA+T0Hu6EcnbqLi3D8YmDTyg2Qz3raUYQ7/NynLZtFzYpKT7vW50TgAdSDWkye5Z9bEMq1rKxvfmkS9DcwsEqIzUROC4BNrmXjxOyjn8FpEHagn9PMEEXht2S9NiyvGwaSmYAEyD9N3Zumma6BdkbyXH2NB2nm8xvmpB9L1WOJiRzWHI+CRHLbafh0l+p1Hb2B2WwRgDiX0fTAAAAAElFTkSuQmCC"},{"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","best":true},{"id":"Geodatastyrelsen_Denmark","name":"SDFE aerial imagery","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,"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAABGlBMVEX///+y4OQAAAAKCgrL6ezI6exHs8AdorE/sL0FBQX+/v78/v4RERH5/PzS7fC64+chpLLt+Pm95Og+Pj4mprQYGBgAkaLM6u3D5+oAlabc8fMVn671+/wAjp/Y7/EmJiY4ODg4rbsgICBgYGBLtcHk5OT29vYyMjJqamoNnKtISEhYu8aamppMTEzy+vpycnLg8/S/5emjo6NSUlJfvsgsLCzs7Oxsw81NtsKsrKyu3uPo9vd+ytODzdXk9PaEhISBgYFVVVWe193P7O95yNGPj4/x8fGk2uB7e3vd3d3Hx8cuqbfW1tZnwctRuMOxsbG7u7vQ0NB2dnYAl6dzxs+14eWW1NtRUVGZ1dxwxc6r3eKx3+ON0NiR0tk4C4avAAAG00lEQVR4XtzY5Y4qSxQF4JVqV9zdXcfd3Y/Lve//GrcDdTPQyjDnNMl8PyBAUnuxa1c3Ae8S3l9fP/+KFVG24rm4IZfraFiBRCqX+jyRiscD8F1yUp5K5Xbhs36K1qcJ4ofwVzVuChCFr4a0/swmJOCn/dxnk/g6/FSKmwOkovBTMGUJ0FLgI8EmgAYfRa0BMvBTxzIDcRF+2s1ZjuE3+KplDvBZw58la5rbklfzLUjlDuAim8Ub7ekJlmXP8n04qc7fjEpwFF4v3d2Vtk/fEKJ/xrETHKfDiThJQOvfwUmilBGCBiETXHhKQkmWTUwZETQ4OMjFUxPx3BacfGsFo1Qw87hw/cQrllPgQD5v5eLxXOvBubmnreiMxRIoHK1PcTpcpNMynOUz0TmZf+AtzSXmsFwfy3oUonOCQe+1ZLr/r7g8lpTORE0yP+Clz5kDsAkZy/lhCSDw8HLIJUxYTsNyHoSoSfDOc62hJcDyQ9ARombB0FsCUFz2jwUIRvvwELLpgILlbNlsgedaWesQ6ljSlXUIH+FJtxzDIZYUEoLmY3gFTyFTC1hWwbIeMuYRgDc5z81PwB6Wppla0PqKRZxx7Ez9NN5Bb80maJ1jMTrHsrT93CHe5UwQopSQOcCiQmfclN7HO2XXhYwgBIVMRkzgDbKHw/xwT8MfsHe6zvOdgzw+posCVmsgYbU+MVitJsFqvXSxMkexQrkJ3BpPG1iFcXutdwHct9e+V7AyzxWs1oBgta4ZrNRLhBljhS7IRoREsDI3ZADckmv4bKfSUNWNyhhjBoZKEbefIjG13Lu4hA+eGMJE1tYiDJEaMRia5RiRCmvf2zFCfDiUR6TwTAewwkhHwIvKFHcwUTshDSxNUWR4e5mduVqEFNtSbAcU0CUDLEDLmmuFdC45SnJpBR6+q3XMOJbU4tzGn0h1eEiedx63O1u7M7X6XCA8EQjn4S7WxCy5wpg79ARXXEfk+WqV58Xqb1B7RvnRVDiQhLNuQ2We3K+E9bJaHtzA0Y8SX92eqor7tP0BWt49gVyLkUJFevb4RdRo9Ai5gIOrEi0/k0Ax6s8K6LBVV9VbbBKPAFpsALlHdmBrSOtT1dJvAHpgNO+rAjvH5B64JEeuAeQa6QJolGFrnd+eU+UB0Aa8CuRhZ6MNQ6Po3oExuZk83sNGurRtIo6wFxiZhEf2O3A97UPNNUCkAEONjGHjVDQH4A8wtAYIKLC6ZI5hqElNtwD30/nblGwDfOHNAaod5MPWAFlY1WMDGFAhdZcAJ6oGw4391aBjDVBdOADaZUxbUHEO8EIP4LW06TmDNIDtFsDODj2BTVJzDFCIYULtwc6+NcA6+tYASdgqTFugqUWnAGM6e8fkFnaurEP4LxC2HMM0bD2RI1qmax+gzkyjbZIebGXpdehVSQfSAfMOyLAXoc0vMpu2AXpk+n6Dfm51zpsa8AjDKDxffwgHdWmDfsOIXYAx7dAx6cJBVjRdinUYtPmbkQ5Hz/QnV5dcWANsMg16EtpwlKA3Q1r/F801+j9COBzIw0WTfrk2ubcEKDKXMFyqMbhI8CJNUOXFX6DkfDgQNgQCyRBcRabzXY+VzQEG9A7YkG7gpr8virxBFB+GeKUd6mwike7DQ72sTta/ldrzf9HskCYMWKM5XIR2z3/+/HI1xFLqtemEX9boazrwm9NnhX78gR2XN1wVIgr+qqONoqtGW8bHdh0ruCoXZfxV3d6Jq7WKjI+tSRhXUlnBX7XTHLi7/q89u1txFIbiAH6EzZV0xd6shNJHKM1VIFoBd6BXuYshn+//GluWma5qN1od4sD09wDJnyTnHEF45OXl5eXp/nw6IkIQPsAn2BX+8nZxWf7E9oUx7MYwlMJaieZUa005b+Yuhg2zyV+WsRzWqbgW76iYt9jR2OSOmXUJ3qj4h9ITTMuNTTos28FynosuWsG0liU9rIDFzlz08T1MqY1NeixbXguSij5dwRTEkgGDYaGd0GKAlzAhux/A+jsouRjiCMLSdhxgDwsdHwQgXz0APAhAYl4BEDYK8DPqI8SjMlzRC9WCMkztIADLPrMRkTmjyA4PYLlmQSuGopvAmt+BsY1Y0zAUSlj1h9EBZib4GMeh/U/GeXnj3TUQ4XIfx5rrA8yDrWH2hpmkhv85OqneSRcolPbjg4Q2MFuKSXtTnCGwv+pwvwLFiNSlqnyWw1PS8K/c3EvV5UqIy0jVI68QVe7VgK8hJjQOkEFMTCq16R1cxwGa9FsFMFtfAfGjAC3EVI6rAMOmr1A2EFfpVI/DEBnqDyMC0f3ojuMCNlArJ6VSUjqJYRs1MUpd92dY4Q9//EnbIq9ZogAAAABJRU5ErkJggg=="},{"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":"Soskut_Pusztazamor_Tarnok_Diosd_orto_2017","name":"Sóskút, Pusztazámor, Tárnok, Diósd ortophoto 2017","type":"tms","template":"http://adam.openstreetmap.hu/mapproxy/tiles/1.0.0/Soskut-Tarnok-Pusztazamor-Diosd/mercator/{zoom}/{x}/{y}.png","startDate":"2017-03-01T00:00:00.000Z","polygon":[[[18.79273330201,47.37078533804],[18.791936169,47.37048036201],[18.79139114593,47.37063268281],[18.7901097,47.3717614],[18.7891647,47.3734529],[18.78721506824,47.37566027041],[18.7860339,47.37764910001],[18.7849824,47.3790513],[18.783695,47.3803226],[18.782665,47.3819499],[18.781399,47.3836789],[18.7793426,47.3871257],[18.776657,47.3893959],[18.764716,47.396699],[18.7616966,47.3996569],[18.7563102,47.4032821],[18.7583737,47.4065272],[18.75879657883,47.40776342073],[18.76199554897,47.41217224817],[18.7630394973,47.41315137445],[18.7659298,47.4147108],[18.7704058,47.4176575],[18.77247285488,47.41808545272],[18.7724806,47.4202978],[18.8086021,47.4404108],[18.8174212,47.435389],[18.8209188,47.4357228],[18.8280427,47.4375516],[18.8302099,47.4352584],[18.8358533,47.4375371],[18.8404882,47.4334586],[18.847655,47.4357228],[18.8510024,47.4328054],[18.8689996,47.4396086],[18.87361350924,47.43597176329],[18.87499181607,47.43342149293],[18.87386045593,47.43248349864],[18.8760377,47.4279677],[18.8605023,47.4230028],[18.8662101,47.4179794],[18.8724328,47.4108645],[18.8662959,47.4077278],[18.8696433,47.4047072],[18.86776892261,47.40207457802],[18.86509430105,47.40052438512],[18.87081279074,47.3983820654],[18.86772375423,47.39699336542],[18.86992005424,47.39655168559],[18.87648610191,47.39477958954],[18.87748924808,47.39494663392],[18.87866942005,47.39462343887],[18.88358322696,47.3899604942],[18.88290731029,47.3896699544],[18.88538567142,47.38530440107],[18.87747851924,47.38339390377],[18.88181296901,47.37604910406],[18.87914148883,47.37392756692],[18.88638345317,47.36922645965],[18.88205973224,47.36772957402],[18.87973157482,47.36640704749],[18.8746997507,47.36252284243],[18.87282220439,47.36136733615],[18.87027947025,47.36062605465],[18.86687842922,47.3585329683],[18.86234013156,47.35637438604],[18.85566679554,47.35199153827],[18.84873596744,47.34728120653],[18.83192388134,47.3384118486],[18.82497159557,47.34257772442],[18.81619540767,47.34925116493],[18.8107880743,47.35356882392],[18.80823461132,47.35599644336],[18.80645362453,47.35854023611],[18.80707589702,47.359019909],[18.80634633617,47.36021180457],[18.80465118007,47.36175250772],[18.80381433086,47.36335130305],[18.80054616504,47.36544732015],[18.79988097721,47.36617355102],[18.79416204336,47.36974865444],[18.79273330201,47.37078533804]],[[18.91871480064,47.4093812629],[18.91826418952,47.40997664498],[18.9206674488,47.41155945729],[18.92509845809,47.41372304121],[18.93473295288,47.41916790937],[18.94063381271,47.42241278301],[18.94981769638,47.41937843296],[18.95154503898,47.41749820965],[18.95689872818,47.41922598493],[18.95770339088,47.41877589767],[18.95755318717,47.41435467478],[18.9621129425,47.40506817222],[18.96266011314,47.40117592194],[18.96316436843,47.39903360927],[18.95446328239,47.3967314338],[18.95275739746,47.39526437993],[18.95201710777,47.39362297422],[18.95119098739,47.39356487042],[18.94692091064,47.39798783856],[18.94410995559,47.3984526281],[18.94161013679,47.39868502134],[18.93735078887,47.39633199249],[18.93617061691,47.39682584676],[18.93122462348,47.39999947627],[18.93120316581,47.40023186269],[18.92923978881,47.40204734624],[18.92561344223,47.40604845111],[18.92465857582,47.40635342305],[18.92293123321,47.40925782918],[18.91871480064,47.4093812629]]],"terms_url":"http://fototerkep.hu/","terms_text":"Fototerkep.hu","best":true},{"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","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-Orthofoto-2014-2015","name":"South Tyrol Orthofoto 2014/2015","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_2015_EPSG3857&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","endDate":"2015-11-01T00:00:00.000Z","startDate":"2014-07-01T00:00:00.000Z","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 4.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","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","description":"Topographical basemap of South Tyrol"},{"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","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","endDate":"2009-01-01T00:00:00.000Z","startDate":"2007-01-01T00:00:00.000Z","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 orthophoto 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","best":true},{"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}","startDate":"2012-01-01T00:00:00.000Z","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":"lu.geoportail.opendata.topo","name":"Topographical Map geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/topo/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","endDate":"2010-07-20T00:00:00.000Z","startDate":"2013-07-19T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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}","endDate":"2011-01-01T00:00:00.000Z","startDate":"2008-01-01T00:00:00.000Z","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}","endDate":"2013-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","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":"https://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]]],"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAA2CAYAAACCwNb3AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAcppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGFpbnQuTkVUIHYzLjMwPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgofPyfmAABAAElEQVR4AeW9B4AURfY/Xt3TEzdHYMk5I7KICKILhwE8DCe7eieiomRByRmGjKCAIHhgjl+PNUc4UVZEggKSdsmwsMuyOU0O3f3/vJqZZcPMgnfeHf5/BbMz3V3hVdVL9erVa6HNhEciCxS7VtBJKvsDJlWUxCjFa8tdk+6oD/zU1ZOMhyttYXYmK1EhMlbgfnudQWgd161y8+jRnhDZgt6+ZdIkY0nU71N/ijlFyjBneAMNTX/3lSZH8k51u1RR0i3KFHZTvrUy9qy13NWvVbtebkWJ0agq0yusdH9+zv5u0Ym4YgfCw0wHY6Lj93zw5Iw8fz2C2WymjxKo91q/U8xmwGOugufhDUuaFpcV9XJ53T0kSUo+VFooJIaHxSXGxifbnE4lwWASL5cUHRA1YmmEVn/Crsjfx2gjD26f+dzFQJu16wzcv4ZvAWU1AXhUVRWGvrSwvdNj73uxorhNpGTofryiSDIJGm2HpOZ9y1wOKdxoYnar9ezlyuKzbSITbSqTf0mMitvfuVW7febBwyp5mykpEtuxQ2aCUIMOhEaTH/qkQHEOEgShHE801wDg9ZNFELwiY4lhXmFWxbqPVzIgFquGWARoYCJ6zRsz/YS9eLmLqYUCE6SanVDQcZHZFK/S0RQZ0a998p2bhz+zK3XLFk16WppcM2+tK3+bzab9dXqx4lmuoH7G6yc8BHQ8+euXPUq3sNiI/sm33vniX54MVr/AUlNFlp4uY+LFQatn/i2nrDDV7XGnWEQlslRRmFslcFSmEUQmW0DSCtEDkkYjaMIjQP4K00sSixAEZnSzypjwyB/ijNEv7pix8jvKVpv46F49qQY8dzw3+eFiS8UTZV5H3wqmGB3AFpfHwzSihsn4ZjYrANMIzOtVWUSEwACHiH9hBItXsbUMiz5q0Bs3Z8x68U3gG8Etms1mhs81EW31+Xj2/15u8ePJQ0MdLucjFtndzY4JLGcKk71eJogiU1VUSeMjAEhZVpnBIIh6I3IoLAxwxSoahju5kTrjBze37v76xuHjj9M4ABaCqQoeSRZZnKLX6ZnL24CJAo29L+HndZcCsAUAAzKoJgNTLe5wfivPUgdqS14ev2cTvOF2o1b02uwNGQawdhIxcEzxMlmnZS7Fq6/9POS1v02rIKN+CVTmRP0BMK7QFq9f9TJFr2Gq7KlbPzghZhP/0+XUF+c/0Hn248suM1eHMsDE3G7MiwAABUUEshHXlAVZNRjCNRgS0Dv+qEx1uj2YTgFI62Iuqk9kkTkO75A4Z+WQ3gvHfZPcptPYDY88fSGllkQI2jcqj7aIWAmeboDnEuAplQGLB/3i8DBFgzyyCiIBxmvDIjWEWVoUdCqKrLhloKnMLCB2C+ik0F7SO8yl7d1yxrBpf14zd/6Xk5Z8CGRk1RE/KCy4mboltYpZ3WoeN/Orw7tm54tyhMXtBAFgFDAk6LpK40NEIAJ+ozFSQ2oApgMPMbser0Izb0MZG7IC6CaS4J5qObFv8i2Lx5n3zNu4mIgjNRVtod8EC8ZTcDMvuqUyD2c/CrCOPsSKrrdPADb/N6bPrQHsXoFh1pCSImqTEItISuL38Ac4RdOH/tII1voncJYjYAyIO0uU8dqSv01JEWWR1w9YatVN17x+jLEqY9xFQvZqyYeMKk1wj/mjVu68fPrjLE9lhzK73Su4vV5R0CjAP8J9AKZKQF2S9JJTVQQXUNCFqaLfdI+eUz4BhVBEofIlDoey11Yw6LvMX44OXD+vawbUJSKSahDU/AkuCrygcVP7LRy7cmfB6Y+PeiwdSh12r+hRILUFFXjI4ZH97eFbAxgg4RRmg5Sja9As2uDwiETAohe6sNPpzVbtHQ8VZ6cPWDZpM4idIz4RSU0grlz5iCNdNn/9bpOOsx//6ainbPlppyXCYnd60EMZRKFidDSB8aE2MRoamx8eECvzKIpI8ND4YCwlEWJGVETF63B7TtnKxJ/txYtuXTx+16a8/SYiDhAK56KiqoCSiFOAygHSH+OjchkAWAXZi5HHyISUIIFhJlGPAaREncVFrQ/q5GPgyxMo9tu+r1a/jyHVrRMzRjdbTRu2MdNbOa3Abge5qSAMkRaGErQoTO5vSxy7feWADCAXj+w+4ayIyL6UvWfEO2vbE5EQ4gWpVWBmM2+uzYxhG391l00rsNkUjax4UQ1xDvpw6glSNuQtVEhcAcQrSBr0Ldda6f3eljdyyJrZu8+rqoFU2QBSVq8kQBxzvtjS+Lv9Px077i7vU2FzeCTONJgWCE9S6zfBQ51DGXw4zmslUaPKDrd7l62g73tvvfVPah+wUBbQXSCBewV+Xu/fYAHgCYpXlURje8HA+sY32U0wpw5sRZ2qJ/072F9PtVWPfnv9yaNGaVFc6b1o/OwigzLW5XC4RfB+dIS4YNBEtykLvmX6gMNx1SFoZtykjJhcHRiJ+4xiDTt5/uR7lDc9jasRVF31RDih3r746XVnRPdYq9XhAa8lFSWkFYeLs2rw0PxcQazqVft+Q0hLQEqJWR2ub0rO9Rr13OS36AmQ0pfhyl/BDyP7cu/WLT9WXI4CIC6wE60XyB0KYYn7EQw0NvTxDeeVSmv/ghILDsJ0zOlxHbQW9U1Z9sxMypMCY8CVfpCAv84TAQiAsQT0irHGMKlnWMLOlHY9222d9+LnGF0xMJjXeTeqgZelObB5s2fYaytuyLWVLbVUWsHSBHDF0HMBJIdAgaKmyiIYhEbVajRQHkRonRwhqlVe5yfK6Zhbdp/3WJL/+tKSxygDIUEgI36T2iU//PKSBy54LROY3eEFonGJEchT+5sQELCAW3lFgoVggiYlKqqCZTDRVfAEBGfIqpdtDvdhW3HavS/MHoacih8GXigA213PTZ+RLTj7QP11oz19KMLw4wcWBjLDarIKHhLG0A5kiJlQRblE0Yii1upwsNPlhdOe/eSN6AxI2dB6aPB+/c/ukjLrRSdVrSS1l6K8rWIbzPxm6soX9hNEWFQxsznkZPzPgL5Kw+lZmTzHpYL853NVF1mDvNDdSaIETdBPyIwgJphMrLFoLHeJ4gmnwJwGr9zIpnrbX3TbgZIYI6gdwSog8QrVRJPnsLELxbljcPkWkKBK6hJCULn9F08ty3ZZAI8kAJEJ7+okugkVX1Z1oqa9IYpFSYZLxbLnrB4EHmEQOhaqzuhsu4X0GBkaJBkT6iQiEp0gSYXWCnZe0ax87cSJz57s0AFrelriMJYBK+XML9+L2fLj19MrXDbAI0qygppqQRTQr/AE+CFqWmjDWEPJdKlYkc/qYTvQKkrHE15rtBPGDqjaCqmstesg4GA6BCEJHouWxR7OPDwCt1Zf9wTCRRwZDmVFig8Ll9rronZ1btd95Oa/jT5BnRq1aZQ26XKSbE5Pp8s/VjKnu4dvfqHdj2cPDmQON1iqJjRxQGUgztwjIrG8fVKLme2bdP/IPGRIMXV4h6pKmzetGCiez1ybrdrai2ReCWGy53q3W2aXHRW9xr2zoc3GR8efMUP6ZkA4E4H0mDd6WKantAMQ2wOWGxQejp/YTGBaQXNrRMN9PVp0WnRrcv+daZ07WwmeV7Zvb7Dn3C99ThfmLdxrKejqcblBJCwokcCiAQOf4AGDaPRO+ktpKP5a/4ULNSn4kQFt4fDpQ8PKtUoscwIeFfDUIg5k4wnEoej1Ok0PU/zOlo2bzRvcJeXQsN69+R7H6q1bY7cf3fH40aILz+W4HbQmA20HrwmcRayElatMqHwQFfsIhNokkiUqp8/1kgJSA7JY6qCPltvEN5n15eRlq34CgKS7D/lrkmrub/Zt6AUsQfUC/5/u3W+v/1LZpbuLNaThk/SAhTRIIh3aq8hi1/D40sE33d5zyb3Dz1fLJvQHp8X11nFbNqTsPPLz6WPW0nDsitCOSR10AoSwP4leu8Sky2X5t6HcmQw/cVCdHtU93eXlZlsxlEhGHV4Rmy3Jxrivds3f+OddKLeOCvvaU0cOHFiA35/Qp8u8EVuOqRWpqkcmGIMyZEgGsczlZOWSnbj2ayBUhaX6YL9YVDiwFGZrvi4LNbywNGNRpmkhmf6xZ8HGh/egkvfxQaL+q5PvvrsU36v/vHZ2sT3/3FslDrsCI1ZQgqXRYW4vc0ieHpM/fb2pCAEKoSzTfhN2d1RYKtB5iPI6I0vN/ZcStc23m2A4iQsPl26LarL7js59uhFxEAijNm3SHkg6RcThXfPrjugR61bcAAoH+MHVgf8S2GjmGkat1iTLLvdtFtlDa6ughekmdhOUOKhVLWOT5hBxtDA/biCu72+Q97vJpFTjxrTx+S1ik9ZqDUZSF4Lit695US2DmeNs8eVmNDbG2BKukt29fOZNpR5nV5j98TS4moaMqEKR2jJ95Z9vuYsQGnsUZh2pRfhJ1dNuvTho3QS+1zPqnqFPddSGV0Ifk3xlqUTNhA5AiiisyGG/cdimpY3wVGHpTF51eFsYiLkP9AcMTjWDUrXiGAQY6BVNG63JPbB///H0KNVcAx5mVvlYSV8+u+ztFrqwnxnUMN/WSLWK/D99kkWQKwXFcPLsmTaiVhCiI8LDWJTRqDcYjRLp+DDaY59FhewTvFho1ZrSupX+nncg/kCrEKeiIHU0xSm3xbecuXPu+r7rh43JIqlh3mGWuBsIdswnvb2+Z/rnW07+cPEILfBY8ujRQTnUFfiC4uCVx/+1X1fALHDbmnOFiMvwugAAYiIAKRrbHs0aNfyccjzOWriBhJhLv8AHc7jlFt9eUKwx8uNGfPtBqWaBqVkvYQd251miKbwjPfnm4Bd8YByCc+glEYxegCG2ZpGqKzzwag0G1jKu4Wvmu/5S2NmcqktPM7uxzggUUQm2byaud9Gzib0HV0YbIzYzgx5snv7XTT6kZF6HRjWWlFfcHMhx+Kefm5TarTGcJEMxP5IeOokl6iP+uWHgYyUshUnp5hrwMLNgVoA7vI/Nw+K+MWFfHAyAxq9O4p3ARnIxNkTPFeVqxJYxCa8PiG258e5mXV9INias6qgJ/6CjIfJiQ/jTKFBtZOw0wJ6GvTj/ZNSp8ve5QdDjQ7wLi9Bw7W3RTffendy32yfPLnmOWiDCOHDKJzWIWw1dM3fZtuO//LLbXZJ41mUnNypGUoW+r+uETmKfkLqLPn0RD4W4DXFIrA5JItRJWhp94EDTsJiKOwbegVUvYwsWLKjTz/TULXzCW7VsfSFaZ6gAvRHL5WzdP7ZcRPGGaaihKlR63MStGXszmyOuxW4Dt5ZDwsIBVGVNM1HPGic2+YiKduqUGhTp6VkCK/IhocC2x3DvHp+ptDY8PpgE1QmI7R7XjVSWUqGlvJlghHWa1jscPfjtGn+wZlc1ko5l2yy/0IPkdj5CqJEJF60GlnFYPFpxN8QSRkbl/hTBYVHVaK2O9WzV8SZp9+z1L9eubMOOHeGf/rqtTwerdVShtvLBLNkmwRUFLEmEiST4RNau47dck+kSSp7CtDqpoSxYbghLmLdtzpoXd6ISkhqtBg5UzP3TSIdlE7as63X7kgmvHnaWdK2wV3r0hjCtEXtP5b+lwesk78nLeczicQFryD2i/kRbfY3j24dERtTBicZ8d1pph1mPncL1TbASkYcBV5+q187VL1XQFNtt8NPgyUPqzKtb3msDoy2KYlfA7+JVvRzNE0hbjBT1l4Y9dv+B1x6fxNJTU0OCnsJSlAwstVtFJOWcLy30YIqx5Q3vD/ytqpegpiswYbvi1f5QcM4VeJZVVuAppi6AcOpwhECmQHHsi9OtgOdEtcf+n6n4TmftW7TzZlcUsSK53KtIZDEOUrOqeuxeWSorq9BLJAYzs4tE9mYGLXb5BIzv35+sEbSj+M9Rb6+92XQua062UDmk2GmHSijC2hp60whlri0BLr9hwItFkBRpNIpNmWFr1+ZtR30wfm4OVZICuzwGWD2QtpnDdf+auQt2HP3VfMyONZfMPEbRoDqAFxoRmiClIL5Y/P51+kfr8cCRgSboCr7UBhXrDzwUWYndEvvl1+mReG6vnSdwHdh1LrDZ5YjYKKY4XXpy3KudYMORnGDMsaIp6pz/4eG9+9s7ZW9DqHtggcH1fWCgQlt8UcawrP5CSyIu0EzovQ7zArPKzIyVll7OpU6YwsM0vt29uv3FxolUqZfYPbFN+37lhwlrC0g6/0WIL/RO8GIN1zYirttl5MnIMAfN2TkrSyU7p+xwZju8biZEROrDMa5ByANbRbIUGxnGEqIidFImTI1UI9QWcep7mzpl5meHaXUaTaw+qqilLuGSefgT+/D43j+vmzv0QkHeO0edZQb4FcENglwgqOS/lrA5S3tbCqzUUhuN0ZNgjHp69/yXNtPOQDJMt61iBip+T1p15JurO2deOPvmpwWnejJs5EgaiXQSER1VI/SRLNotlnOsCeKL9a9B9x8sVW3M4JKtMYq+tWsoTABnAIoI3suy0/TrmaMDANn7PTfztZbPelcNVJ+aJbBBbbq+ZxO9hyEGHGguCIUAqWUlXK8z7uT7SKijwFYebyfsBcLj75VFUrX6AQtOF8CZk6kH+G1zCtxSMqrlqPXTj9w3J9/pjck5+LzV6w6DixgEGCRILajgOgDlmpliJOPeQC1hBqNY7oF/F19ehaQUDbwzWaFUOYg299Y+8EQ51kA1PHKpPtzjI7/m0w25D/T7y7LOTIgig5RaXZoFGobjI9xOw+Ni476Q0jYt7X+5KO+xtnOHJ+tVsVO54hG14DqwbFX8qjMU9l024ecoKfyDLycu+XDjkR+/e/3Dd77b7yi+UXV7PXzjhtTKkLAHWrzyzRUBAIbdGikcA9CM6bcP7N570rqHxx5DLhFOa0JR1kY1fbRPavRbOnHCP7N+eeECc2NmvF6dRivCIQ6dVaRWkdGsbXiDtU927vViGvsHRiGDS5orrV2HvzBWWHLwdHO/uyt/PLWvCEgZidUC+lRN9fCDTrNKfodFLuzwFufM26+q6T0FwROQFv5svi+fmiW8P3H+SzXu13NBKizt5oczqYeH89N6fI4g7eJFibWIiLOSKTUF/yDh66ndx6CxX0P8a2Z9Gas/C7jkd4lvarPmnYTnLVc2gnJ7SDVohKL3hNcerj/00wzUM+vdkn1kLq9S1fx1cwJh6ZnuT9Iz51Rvr77f0i/ZJ5df0Mk3K9hdhTM9VQKbGlZUWimKuZ1RTHC2jWKlj7SfOfzEt//8buT+RZt79F487h8XvZa0vLJyGdwc2g55btafiIZASVho4D9O2TRmOkfTsPgpe+etfzmLveWXGmUkNUiXVB9at7j1iaLzmw/biwZUum1ctQNBCm7sBxhNRrGLLvJs15btR77+2JQd26hp4kpXLCl057pNosYne59o2dLZc9HYo8xjaa14sLdHDpNBEje5Kqr3nNveYeayKaQp3E9uNVwF9e9+VyumEvGc2x4jhtbHcVQCxwBo4VqU5fN2/i7/vNbJFVUSI6FmUxXhjsysLvtBai+hU2aojNXA8f0kWKnN+mDKwPNUrDexrpFhemK9OnY6fvzyubI8puJQmIA9iBCsmPxVXV52Xq2Y2X3+qIOHFm1OB+1K5hSzAslB+FQjEQFa8trVCwvBOiQpSZZK3A6rip1VLHHsilZnitPpJZOXlUZodBcahkcVV7isF42SvvsFe2nDS56SH/ssHL9+97wND/35hZn5Lpd7YokHqijWAzjAQ6ZhLqQDfJATBawMWPPBWwfre0HRRhtNYpKo294uvuXITyeZswG5iMETMy5jrTHaJwFSVkwcvzc3a/UFwaNDx2F4kDRwV1YVDXbT4U6UHNVk7UvTV81sKwguNipZyzbtJ6K+5smqMVr/44sG+oi9Ea6y+y0uaDb1SGLghuR0ueTtpefu67vw6S3PjJjxWFrTpo5giOD3SbuqND2wGZ1PSefqVK+Yhk22l+fysxN1MArZCDTMLzOCITpNOv86KBV3iV6vnjLqEnLQQumbCSiexJl3pFXcMO/Jg2Cof1Khc+BuHYODPy9QTFQqvR4x2162ZfDKaU9/PX3VBjPWI34JSTK7Cj8y+KG6DH/R0F+kR4pGYmfovU6vM7XWhh3pG9vs2ZQuPTpmLX+rx/dz1t15YNHrT+2a/3LPnOf/0aR1XEIXtOKcuOkF85dTVjzTPizhTzeYYs4nhIdpZQ3cjqHPYQwhJEio0F4VllmgDxCHGGnSa1vrwktuDEscn7X0rTuIOAh4UqkweOAYGd5H317Vsvu8kd8eqix66YLHphPdMihE1Higk5hMBm1yWMLJGxu2uHHbjOcnEXGQmwkrgwfvdUMcVXMQetRrZenYqPFXTRRoBIoXi5HQFELFyKcJ29vyT47C1FWbF2U++eoLf4KG4+Vckk42htorCA0NVrU+xDHpjB3JggUOFxQILtowuZGilrU2RIZC1Ppa+k3PiGlSAb3W8EGEXgeEAlaFSIS/tHdHG9zlXhc7UJn3Um/z6A9mbX8rjtRHFFNRX9B1VYgqq25LDqZGNtaHsWbayAV7zBsWna16xAdKYljNsEzfJtT/jZpPa+jpw7ZsCB+1aUXU5tEzv9+Wn991yRsr/tpEY32yzGnvbmFeg42GGDMaBmNIGCY0wRBxLjLC9O7tbZL/bv7LcBxJZQIAxiBnqOl+C9WdK6eN3Z15ZM1Z1a7HVr8Hbj4i7II43SSL7SJjWfuoRi+Pnbpi0mAQBhEWierNo7lzXQDl/K1e6cB//1dQ3KoJRrUsgyZM0D8//JljtywY8yFTHEMVl0Im0KDuJlQJ7ygdlsLRwV/chS0rsj3b+5jHru/TqtuS54ePLSS1hBAh4xq5NQfMLwTyLGXw5MOGNqFi0OQbXnj3gpmaAmMeNOfvcRN94IAM7nD723n7P55nEYVmIF5iuJxwgrVBzyBJ1AKrRS4yeh4q2Lat/4DlExd8N/PFTWAuJEWwxk2tcqEPVkfte1JnQ/SeyPCoWdtmrNxBD8nsa2gUA3WHU54HxMGwMNQ+vH6i2KTUIjRt1VkzPm08d0qj/Hc1bGjD16v0eeL1F5rm5l+68bylNAq2W2+rqDhvUmzMkXfGzj1LAFID5AZQBIL3D4A6/r2Xmu8/dXTzLxW5d5ZhrQFB5KFVlwdrDZPJKNxgiM7u1qrjqE2PPvvtF9Oe4wiAatQAEvQyjx5ThrPHp1/44O/cq9d/VBJ5rvsU3i9OZesZ69C8zYKi07ahZ9RyrQYjgEMM1cioZjf8RKKVVFE+VVEinjLpJ1hP7XtyyJqZyx59dvmKNB8iCECE3+T+X+ay+4REzeaqrgIAgUszA/uXmHFVXdf4g3N9c1qa+5aF4xYVOYteddnh9EgUUE8FEDOURVIdHs95wZnocAovd5r72JN3rZw5b9v0FVuhfgIJmcbcGQ4oQdYntauW9izeNInfhIhO7TQOHJ1vyCk7zp83rP1403155cUDxywa3T+3olS4ALNsg2MHNL0WjKqINoXtjo+I/eT9cfO2+yvVvDFiSg5+04enbP/3u+PmCeQ/FNdIJ6ePNnOzMj26Z83MUd9m7nvxlGw3wFTn1SFCCYIS0FxoEnRGlhzXbMP8KSun9REErmunpJhZRiYWhiCCOV+81XjfsV83HXCX3lMhO5fzpmLO0SSHYoE8y/X1pxNUS7P0xoipWXesmjolX/C8YLU5vHBO1F6tE9gE1GgkEBPU0CPuUlOmbFuSPWfEiLSXFi3d8vT81/k6JCUFC9WUoAvVK+PgEyFwhvSLqCtP6v7CBhi0AoPBRyB+4VM32+90hzNBMxPhgPhaz3kj0341Vtwpk886HW6qJ3FdDJIY/otKfrlVzteKPa2Vl77pYR71TZQhZtqOmc9hd8PMGKmlCzL4WfZQ1VFPObcpyuqME2a+CB7DXl7+4PS3lq3K8dpb5sOTEvv/IEuYfoG6uR4Hy1UdQEND94YVheNaz3jkwI3N2i77cLz5Y2pk5OZVD2c7Cg98+8yq09UaVbPNbzqzcWMLDu289vy0O3LKC6fvK7pwW7EDm4+QGhKOCUOzwqLIIPUNS8xp3bTF8DefmJaxdeoq7tJ+6nJSldS4dcnEB9L3fPfqKa89FuCzSFjEuF/zH2EfpNqg8J8+dUj8dtrzq29bMrHPLjX/QdnhcsMnTcdtXQHWXbscroHSeEqIICmywysf1ZS3ys8/8doN80c80alhm7n/N272D+aMjGtSu7Bg5LUFaYbf4mAgCzaKoePVI0Fo7ZCZWQ/UoVrw3Td37lyDs5uZ798dXe8YVrb/i1/O6rzNNR4VuyOqtj5JQrWhT3QYEschVTmnsoLl6G2Dmjosg25fOuHNbm1vnL4+bUQRqvcHhPAFafBBceWvBDEjcGpKT+eesVu3f7Pup0vHHz1vh/OGLHi02PsENKBHURuF8C4NdAa3Tqu7iGNblXbVo4nQSD1OluR9NHDZM1+2a9Pur0qlO8dl83zUY8EoS5Sg2WbXas7FR0brC4sKaQvjxkXzRtxazjwdc3G4B34/Xh1UCjc6gnMBmg7RcayhKfr5V2asmUuLcFprkJvJZh/hKrTo+ipj55oTtuJHi5028liwa416k12mg2Z/3ARjBk4ICWzn3HVDsbj8PEuqHFJpteE0G05Q1Yu2vj5jt500H5hbBLnIalOKdK5biy4ey+i9ZPwbKd37TFnx50fKSK0Adwpp0OC+v/UtvfkIKwzno5hJbwiVk86zh1xMX8sM+c/1UGsc/4Gf/JTh8rS0oj8tnX2zq+LCz7kaWzOsKMBEmO5qjfmf4ywahggHanJUm5RjcT+e/2vZ0LQX5y/b8syi5fWYzBkRCK9j+N+X3PfuZ+9vOuCqaICzwrIRZ3dcGHEEsdA2NUWwhobIH2D23ZwQ3XDv3U8MvZwmwMSINPOnbYk/HdjXqMBe8UR5acXrI/9y34jPM/akZJ069tkptXJhCaQCKyghxzjf1o0b1wocbMCJsOTSubUia2g0MhgKDndq1PaZd0ZN/6HtzLVVUiMg1R57ZdmT2zJ+WHPEUxkBdUzWI96RCwEt3NiCbaLXm3IJGNi2ySzzR0sgDuKafPd3r3nTvbctfvrVXTrvk16ckQC3plOG9bDsK72l/ShIHg04midPsUn5gvxE5U9bBz+wes7oTyYv/QxmMOCvr50rpa7tF5kkmUarKbBUuAut5eepVBbcN6pKQxUCN1ZaTXlwZoHKegC9wQFDL6iryvl/kJ9XpaKYUlt1OZj+zOIVuE3qMsfNDEhZ8q74bvSygtQNK2/OKTq/e6+jqKUKtRwqH/yPr96On1AomomKmETek4IlvKTo7LIBSyfe36lt14dfSht5nqtcteKqSbM+fitu/5nDz+/KPfn4ORu5/Ekeg06rcXghNySdlGyIq+zStO2Et0bOfNvfF/b6CL5sIS4ij+17F1ml6PPs6i1bjF9+uyNxDWIv4brfk68+f1tW7pkxFcw5yCZqoitxZsapk5heo9HpoB800Ohko1b/U1xY5GvfTF/1Nvdf8G3wMPNobsVQEOol8suff1z//cXjw3Os5RSSB3suGhGxq3CQQW+41ZhwuXPrlp9tYh8wMzZ2zGj4j5iAuLRW4ESyc95LT93/wsyzZ8oLlx2zlUp04g4UIiGCC+fj9fXPhwiQ97QtBX09izkaOMtzP+23ZMKyH+eun1O9nbr1hK6elAjEWRDOuu2Vq1aNJrcnhrquEEhmKgqnMxxxHGqL1CULDuzLExO8xsT1JY0Gu9RqKxQhAqkBDBmNUrBeSx8/PX+Hqnaas3jsO2c05UMLrdhEhusRtttCBpWoDgLGByYQHOpgGqXYavV+77T1unyo8vi9G+c/+Pm4RV8hL8frQBlp+6+73vmV2Qd5Ky0eHRzRPJD2cFoTm4RHiV0iGnwx4OYBo6b3vyefCsICpUlvlKcyn4WLryM3wcIFWzPLcbnEyWlpJFUuBCp/7ampO/F7J4VsuVSc0+d0fk4UNnLcjQzhUuPwuLJ2DRofWfXw6LOB/HQQ6tTly8RNgf2M3bl6zpD3f9y2+bTqaqg6XF69Ros4UAhvBXWsdUQ06xjd5I3RUyY8PURIslOwL5TjMAXq+6N9A354CkLb6i9oPp2yYvnYd9ftMJ469topT0WnChvWajh1CM5MQRSumqCjE4LpcAZdPldRouaHu2YPWD65+/ezVt9D7eDDibFmRVfwveZ9UCcQy4v16A0RCfFpc99rN+eBRw5hDwuWspqRJ+HcVMps8NaSVSdgDaWK1a4ePADTqnoN2KmEJ2rwlAG8IC+B/ohLhxypd6+c9vhlofiVw+4KCYGvEL0E0SYhRYOXrnkXIfywPBF0Gq/gOe4p0dsvyV8O37hkztvj5i7j6igObFEJKctaZvLCUcQAlcopexDkFYsKfYKla6M2z7w1bvYbW9kL1Z0HuQVqxpa3m2XmZD3icrvuenH+iKRchxXAwUQ873FNpNZ4IiI8Ymuflh2/Nj/wRDY1snRI2iV8VW250kXASY4lM23KELMmg2V4A/FwZ3y7JerggT2vZpZeHHrJSctv0aMXtBqXjHPbBkg1Y3Rej2YdR78yYsqXX05dzhehOCTDiQqZ/9CJ1C10wEseAi8Pm7gXBNN10Mpp888qebNPq07ovbKMdSGc2eDeU4PHBu82XK/BVrSqHdFDvpdzB6csfebrjDkvDiYi4RuLaWm+gldh9tDO4KSlyCYj9tJFIYEKBbNiIZPE1Wevl/ZzrglZqS70Gu6nAAIMgK5DJVov+ImbbZ2+6s2ZH723M/zEnjVnbaX35mNdCkqDFVDEfirWZVdJxGiwwajVCpJ8wVIu7C45v/S+tXNLPnt2ySZS6UhqSVhky3YEFHTKLm3DiEjWJTzhq3v63jZy0m0PkhjVpGAR73MD2UxqqHD3qqkrth3NmHpCtotONyxcZP3wi9IyWthLlrZRrvIhRaXFnsHPT3uvS8sb5q18cFjulPdevivfXlnx3sgZVd6aHP4DzJNxwHeufNn2j+P2Hz847ssdX0/K9FTGMI9X1mKMPThgROuNZmGRrH1kwlsjn3jq6bREBAhIYVLquC2qz3fHzKv7/82fzQe4SgGCIcI3j3tn9btJF86vPucoH5Jjo/Nh/LQnnWa/Kpl4oJoBaXSy0+k6oi0e9Kflk5d9N2v1bLawPxA4gYsNEIB/WRx8BGmaaVnghprsUOA++z9MnLjRPhlxVjz4yDn8vO/B9eb7z5fkrTzqKGvr4dFL+Lhdk7SFMqiBe6ByprhArbRY/566aUlm+ui5PHayZCcvKZwN6KpPqOjQoOmU9AmLXtvOXqwuNThnfnjtopt7zB/x+iHZ1km1Yv0lYi1AthOSjdxNhoYPo4x4rBVOh/qrYtX+Klsfz6soSRu6fuHQTs27Hs7c/dkbty8a34BpNf+AC8HppOg4I4hMLrNaYnCm//Z/7PzqT5dke2yx3Y44DdgSod10FQxBpxe6aSPzOzdpNeb9MXM/+3bGmurw+dQqEO/143Ly+2BPBklF9KvzwjTtxkcnn0Gt9963zjywSenltSfcFZ0RmhQaCc7ngC1x/K2nWTLjgtnoSysq5FOKOCv15cXb08fO+56fB4I6gRMOJLfqT5heLwxhdrfPalilEtQsRZIJxAbrSbUNT0gWEo1XJeaaVdV/RW4kFLIUah77aIL5U+T+9J4XZs44W3pp9gmPLRJ+fDIPrH0NahckLTRYrbdQcUsnLpx5B5vj7chrWmokGSJv0IfvfvCuB//ybG8ejUKE1PA7D/qkBiLNLd1bcHJWtgciTIbfuUarBdVp+cFlrhH4OoKR4T+gClIgEgrn6DmkFphckvC1Z89Xz0Ak3pVsfup5l1dYVuq1shOWQkhthZXhAIsVh16YCxJJ0DgwjIicx3TwKGZNEDmxbUTCG08O/NuzPIxLQGrAJR4iUDZ/9UbDvYcyE7cKwhGuMlw3fln1T+41P0V/MsF2Aojw2UTzdpTtAheKMZfUklUnZWc4XHMowNtVTcKQJPD706o5TguLz7+4CvUkY8eML2midXAf8SKuFlA4GLHxe+BBFAe4POCvH6QTWEHpcWCHifAWwsGrqhyqh/xJiUyqbv0uPwJrIOCsRAzlqykrnpvx7aa/h/34y+JKg3fCaUsZ9tkgTXhc4/qbBJFI4ADu0zpnixFznhqH3C+Kt7boOPnHBS/3JeIgvcvvPOgl58GHNiy6CQh9ZJ+tYFa2rVLVyFxs6UAc9XaTBpPy4DyYTo/gecdLCuT91twX+yG85gHzq1MHt+/doYGsec5jd2RX2KzYDoEQQCER0TjC4F/SQGeUmkv6gt7h8R8MaNejz46560YQcXD4xqXSbj93bhyx6flbv96/98KhoouPUtevHrSBcv0xkx8RZEIE6sH3s9b9/b6eKR1vj2i4tQGiTMLED74U+nRfoNeQJBKcEr3FXluPxzYvuxf3udyINYSDrZGtKpCz5jesRGBeAuYVgbK9tEaulbDBR3ewu5kt2Oz5WK6cZF7PGRUfGKpPJUo6B2EN6g/RQq36fuMlEQcxSFK7nrtjdMWBRa9O7JnU9s52hqhTEtatiLZIx06v2jZUUcnpdLIKr2Pq6t1bjNJrY2f/RLBwCrxMLue+g0p9lk1YvDv35FzspmMIFbdGo4H7Awb3NyZEH8f+oFa9VF4h2yLkpZ3mjtCuTHtyIaqZad7/xaIjew/0PF5woV3bqPi2JoMp+uDFcwd6tOhwqVF82+/XwCrGFyxwCUjBgqO6S/zN5vGL/3n2wNxcyBpJ8ZJ9+o8RtKHa+BVlZdXLaKplrfoZQARSu1Y+ODIXDwYNXTt39LGCi38/4ayEoiSA3YS25BCG4AAWy4HX65niy3/DJY+Ugqg2dh8NEImEwCNAi0PCDO/jqAs3LfqRytd89Bh9V6XUVMmTnu6Om/vUykK5YhpzQJSEiP9VVeZf/QFpi60Cj5ksdBlm8f/GzPkW6+aOt+CIRo7WOu5SZbkKAvDFC6vbA94qtCB4bOJMupY1+Xrnz0MkMpvBzYRczjkn+duLi5KPFWW/ftBa3M1ps9ELnOigAm1b/MuJFonQlcVyq022GGUziETIWvK62dyTnzTbiYp3Hq9W+6nA79TOukH9BgjffHxUzsjwwXf/i/OSzxbmvH7IXdLN5bLDumXQGplG4hQSKPdH+b6dAxpiqup04grWVqld9M6MdPVDWF0e2bRid/7JA9vKBU+j+iIrUq1YGsAM5mVFtoqe606f1k9s29Z1oPjiL6JWNxjnu9HOlaYCUPjuCMyBRfqlcgRg4CnoKoQTSqAcvjnqFLuslZIWR0mrPbiGn799bFApCIRgUOg4BNQ6gnV86npzznfOzOWl2LCGeZdi/gStm/qJMkIRwv5UOiz9xfSsoiri6L/kmYV78k/sP+Io6+a0O0lqgJiuvgBEnVdNBBAAE+FnJJ9V7AtwqOUNKjRwxqgoWMa6Ba0AxyMpvhJO4nuf3vJKy9uXPrNx36XT+4+6Ld1cDic24TUKLO6snP37QRsCKBH4DgpP/TeDDnh9RTIQ+A7Pqcmrf8gIUStxh0QgQpsJg/TvjZ55tH+rzilttOEUdoFiYoXsCp1hg64NhwRP84O7PmtJ1eKkOL0bCqWCF+N3cfANbkEsUdUnURlirPRdK9G9K5+YGICCcx2wEwWvuVbpmpdU5Fo+NUv5rzbDTEvShLYS0ieYVwxo1nF+NNR4jA9FwgiZoKpifBAFWfX2kGit8bfNS7tn5Z5/42d7QXebDS7nElRaQf23pEaw1olIMAmiy2b37NPkPX7nc5Oj/zlj9QMDVky596aFY17D+ZGPEsKj9uBo6fksp4PdGRkTVVZp61rutQ/YdvCH4Rc1Xi2kBkUFR9xYbI5gbZpoDGdt9XFlpCemJA1RM5gvnkCw9q/lHhkayKx8LXmr5yGWdfWEajHdsF7z/QEwibWI6j4EngEkAPm9GnUAkzGXWq0olCgLRw9Cz6DvcuSrgWtn1n/jIiL55Gnzqd6Lxj11TnG9objJgy5Inb4GCBAKuCbZ7I4WuHWiS2xjZ0nZRTCbGlX7cgf+whAFWwA5rnamW4G3dwUe+79rVuB/gREd5GCcVGrlDnH57BtrIg7lZ3+Bl/bE4Kg1SYE6c4Ib8C9XI+OMph3fzVo7EqJDxKfGVIBA6Fplo5j2wwmLFicvHH3zAcVzD/kB4m7QJQNwVCPDYKSJ0PaUbl3y9LifL5zYcAaWDZCMb61BC7n/UIK8hfFWoy2ptLh2qMr9nec9+eH3M18YetO8kbkXZfsbZxi8hUsraFfU/ZOlXEch9UsU7E86ET9Kg/NdoqD14ugu0+lYG0OEvY0xcdrWGS9spAHM8KuJQUEn9KtHvvsWoSJzgHMUl5f+Zo3SAGdnpKBNX7kJZRV7RuRgSvfKnY5bj7jKWuG1TGQjD56gDDSTTCwtuX+DA2zzeUw4hfas0xCIBIPE2J55G97qPPexRVleN+LKIpJ5ED8ljkHQsophPTx2+TwflUK7dT+PhYH8fE8wGDSAugIuPjDdc/z4TwTq49INbR+6kCsdt+b1KhDgz1pXePqgo/HWSayBq7KI38g01yEifzfUlCQzmKeZdUxq8Xz+ecs9l9xWKFLBw/7AmwTzIbGLzkpRPF5e9MQZOqiEN3lh3khqhGrE39a//4VFJIX613vwcpZMV9mDPcwjd/6y+JU3zy17W4h0CevaGcLcsUadsViUNSWykwMk0EsYdVpjpM4gtdSFFSXrY1endElu5ScOAqoO0lSH1IAOh8LBqsKQrOWke1rKTL6yQXXs6tUylpnB270hvmkPFUwJ3Cfo+Pluko6psHCNBHs231OoBFMCG1PcuE+vcKvx0eMcP0OM0MTwSPKgbUNlOnXqFLR+PFLJ2Q6zjoA08lcM71oEstXgplS+eiKmHkhNo+Id0UAYVINRCJ7AYwQVOnyUwdSL5zD7+h489793N1/nhFIp4IAqXoCqIKx9rbHh1yoYOliA1ePlpx3gbhSy0YwFCzjTS+7Z+xDOGkFQQqUMabOjakgLRegddLocHA0rKQVnmkPW/7s/ICLBTGjheerOclb26zZ/REG3xq0HvTt6zjPPvP/KsovFF+9xOO39LtrKowvwuq4GEVHaaJ3xAhag27u167ADgZqtXJmCWY9t2nTVoA2t4hsJ53LLKaYT73zwDgmKBpRr0uop/OU3Ph37KkSS7hu1M+UF8fQLa7ag+AVkBFfAe5FdjspThbknqH2OoDAaYY7hN11XHaLlMuQtK8a7MbIunee21fqhSUGBDHbSZb+gMdI5bh6lBvdqJgKQqsZ5f/h7mjgRNUhqdlxbcKYc0Ef7H9fpB6S6KEPquF3ODrtV1cgPstHaCERZs4Xf5wqijS8HaHyoldq10k0ZDKe5MTI+Cw/9a7La2fg1H0r8eqh7ivvzrZ9CXcqPxsE0eudMnXqxVgbfUtQ4nUmQaNr4CAVqCFr9f+amv0kdPCDcR9zOxPILzgN9Fo5b+OLfRprR4uv+D2+8hP/1/dlFXzgaPApHgzdvR8zVa5ggMOpDfJVIfAkDEGxGcVuwwD3/QllRO2oiA//qTT7kUO5fY47+Je9kJ4prC4wOKqi45QRrw0amiNIR9/3Z+slYM8P+hYBXwBKjCJp8BISYtTDcwr2/LTL9WL9pOIPX0ys6MelnRylhVFDMpeawtmHxiD/buXFzdhDXdHio3exHT4OIbyLswK06ayJflEcBUditjd9/86XmyHPCvHChYPbRGy5/j+QbjFvatBf3HbFpSq2kVeM100GrhkkWBILJbEMv2uHnXkIQbGCIvz+zT8L5IWgIcAIJQhzUDM708mPPyISQo//jxBEVG4rQl+WLeCPREVfpgi6zHzvdc+GYBzft3+9XdfxAwhpBrhHUB4aIkGSloOO35i1b6F7QlEKMGinCqM+MxFtNMSoSDUCwzBhEDb1yGd9/mfX16wlkwIC+H3KMkn0RDuFt40q1aBTivMSyA3NRowkgO2IPSyxSMh4fktTTTg8dbtchAZEKMflB4eEVgPhLsHgqtpT2oOsQC2OeFfDyvkIjuJXhveWc/fqe1P5LiyGN1+Vx4A3gVVb1MFF/hHbBOcrVLoFrwAnTiOi9iDXz8ZKcAZTli0Z5dQipZtGMwGXQcQk8DHwjEx+L4akTynASMAcEi0f0ysa6CTdpa14pl12RedkXOlCO1PT0oPNFhEzP9/16qElhZWUsFSUtJljC6l2maPQOj/tQ0MqCFfpP3wMCYSgkuHm5PMecFW3Ouys+XP/JhsNweFz9wJpZt9C5FRioPP5QqcqYj19OTF236HacXPxoy77PJhB8FBCsNpxAcD64bz4x/TT0+CxCALDsegZc9FwQnBG7Dx2ZSXWZM83YK6r5imIsxoWAtyflKagsm0NvJSIVhK6DJVotR2v1LCoi6rvAc63eeDYacaZI+wqVyIXEA4vKZUvpPWiXv9MwxbebXh3hBP/7OJS/vrK0W7a17EZy90WTQeEB4cCipLJYU1jhpEcmFKJtni9WF5YR53vJVV29ww8gHVByIMig02mfSrewsQwX9Jrj489KX8Kg2K4+AiJuHbqbV4r4c/WHkybeGJVNBAKLatCS/CZWdQVwIMipLHiUKkn/cbZUm6nRfG2ryNTT82MXztxXqgMsGFZOYHSzVvLXy8K1xmNBB7BW/v/aJV75RWtMLXRLuQTvCD/mKG2zszRn0vZLp3d//vN35xtPf+hAzLSH9yZNf/jA97/sOrszNzPjsOj4S5bbRtybZYQIXk3uB/Qca4vPyfqFQGBBCYTyYDYlJ4KeHyvNm4wACGlw0nf73TxwHI8jEqlogagvrN/ipz/YZy1qDsswArkER0i+GFQUbQNZ8uD1YB9SO5RwqOknHU0TEL86tvue+v6Cm5GpxXvBa2/xp+emrKC7GT5rHRblgMcHk8r3i/DsRE72y/mw+kGK0JH2oNXiPrR6iUVrTfs7C4IbUhlUythNbTvsivEiGJ8iY0svODrzPuKN58dsxS0HrJg0F8V8rj90pJc8Hoh4fYyKcKsKLpMGr3XnumRQkKh5X6q2hovQGX7G62qIf3CcDWSp/o3BgTu6W71QUTT2kb8v/RNbf8ZlDph6q83XnjXpjmkfvdn3YvHleRVWKxlTeJ+r13Xlt8pM0JQVJu64rgiEAKSRIFcJkDh2lkTFipfFWxAFPdNRHnEJGzdlzHtznuLpccphDS9wO1wqkDkSHq28cyGCNgTeDdGzWYdPuujCIUA9eD1l8ImikDv08tgSBKc4XHD2H7eteHbtpC2bunLQzKR9MPXVzN2xaX9fPLinedSBXZb8h+AsSJEx6hlw+LDptaxpZOzHLzz41AU/ArHnJy/PbKIPzwVq0e5CSKIlkCrsDnVXSc7UWxaPfRMB9rp8rZ7WgzgU+mQiEMbjr6xKgTXwp1/txX1w9loOtuinMaJe005iks7EmkQlfkb3Elhn1JMirfjr2OxYbfg38KCj29Co6iaaH6ynJBzgUg+V5i0euOzZdUu3v98AjIT7x2UQ8UI1RTYO1/gPXupx7+qZY6DQPKa4oL4GMUbUbcV3J8Jg3BpLQW7grhR8ttAIuiTh5brnnFZ2MPvkt/esnTV75idvtOA10Pig9LKdWxIeXDd37PeHf9px1mM3IrQSef8FrRIMEuSoSs2Z3jage999QsKUh74v0sj9/ZPsE4c++K6rvxLUAnSqKtAHNAR6fRwhntZk95qt6z5eyBHPNznBYKe+yX0Wj3t3t6XgERy2h5EodJA2ag97SWAlBrGLFg6zsnwEQZmsOrjdRGh17bJdlZGF8GeiDSdIFDJ2BE2+ejxq5+hEcUCnXt3XPzzmMLn3kAcDIRJUyJe/Ljo/RnDBxwPSM2gluEnrJqhM2JKWhFZaE4LySWdtslxA+Y1MbOiU1FZn8R4hsIqQxEF5dZAsbq9L7B3bpHj+hKmtB8e1rSQVJC09jcfRunet+bb9+ad+wJtwZRy58xlwqGCtBM4KR2xVjQg3io0UbWUDY9SvFYr7V6siu6IlSR+nDbuxyF7RDIH/WuYqTlYJB0BIWcxfcCmLccI5VlXzQPOuOz6ZuHgAmuPz1WbWsENnPNYbcN4YAx3axwwMT4HTK+LDG9gNYhh6JByrVBWLgak6k6jpeEaxhyEQBqQ2XpRbj68aYrZ4FBxd7W2Ie3Wv+eWR9XC9WiPyP76EqkEUzwmYSxlc0Y2gbCAIrBC7dJSX9Wpxw7SKrN1Dsf+ih0U3pGMftYfAU4KMwADH7IUaqGbd+MEwLCaYFXtyOIUGwgDKhiYOIDUoWPHow8J07WKTniPiYCkpEsyRfPFvhpWsSXzT5zuWFIw5rpRCm9AGNTtSdyAR0Bp6ixNLODSlwXv2WmMzqzUXuXQ+H/sEeG0zAtGERiIaKwT/9iZGRunaxCetJOJIgUqEfhDHl+mo6efPmnfetuTpr/KY6x7EbHaj/qAGEOLcdGbVYoOEZ/bIU17r7UzS3q7DNuM5sk/jKAOFMgUDASvD3i7WUqGIg/pXJ01oI0FdklvGN3qlqOTSSxWynWRJyCDpdJ6Dv+DJ6ZIP0wuftNquPoMiTQI24nEaAJoBnVkOKQRADKrX69a20UWpXTp1WkaOstedilVnoH6nGyAOHj5m7aOjL7dNaDw8zmAir28EsRHoBfNBk9/KIUka8F2EUBUgRohD60Ss8viE+wi2TmHUR3vl4FQuptPoeoc12IVXyfFFP/zKuOpC8JDE2/z4xLOtYxqtZGFGrKvx7okQsFAb9AgfmmewdpFWPTiAgLe9QBUFZ8TpwtCTT8QBu78b9kJdB130j+8+vWAV1ZlRzfuAog3SvQG9+o7qKoWDAas6vAKOjpEETaS/gGphmwPrx7gITo/HbXN5ELDBQ9cUGIHGDnSNmAzBJUfQiunm+jNEtMK3U1ZtaC6a9oMh6DDmQdyIr9TgU5ugmmt0FCgaY0MbrwwLKgoJIeClMqH5KbYAEB9b9SThxUM3JDWf/WrahPMpYB7/zxAIDSNHBizYP528bEvzsKhHm0RGwZKIE/kCYixhgK4Mdc1f4DqE7JQP465qwFZD4QyfASAi+LniCQ8z6nuExf3ytznDSWVgZp/J+Eo7/veZfDn9uRm3GhJ2MYNWh/pdYHFX8tQEhV8RYoIYiJY4TIAP9uvQRQAPqaZuvL5Y110fc/yhB1MHU0V+eHid/mswkRTJfOdf82IiYnonavRWnP/Q0viEgolapdcSEHFiCOk95siPw3S4Jq5OY3ctKZAL39Q9nih8Kv24qUWnv7ZkRhvsckRt9RIJ5UebPnhovgBHfeeXiHEAaCjTqhIRYdI1lcI2fPTMUjKGiBlgHv9PEQgNHsMxTbJqHZy/6d1bGnV4uEtYvJsjJikx8CMkXfa3DgrnzlizwHwKIw/eCI5VYKzRpO0Z1vC9d+ZvvnW00JMfDQVCVk0+hwWEEEDS2X+bNLCPMXGXZNDrQV2kTnnAmTlQ/rzX/EXw4AMKIjzBG4NVWYwIN+l6hifu6nfL0BvHd+5v9UeBqQ0PmEiGl8Zn54y1x/u17NI7OSKxGOs8Hb3MFdVymLiZ+JqhCZ6RKqNxJsIjKQ5tjd5hSBKpSqWjnfEUcPHXnpp8pkNis16djNEWhcQ3TmOhLCFvgK6CNxLiLuBH23yeiS68cE7VNDCaNLfFNH5u37xNT/NimEj6Js85qMkYJ+43r0IK/RE+ONgGONEDwE79AAP9DYmHxAenTB8/9x+De/yp9Y2aqNcaSHpZi4BgOJkHDz+qlN7XwieBVDBZDwLAAl3l31joYmowqWgfSEPSWaZhhk4RH2bSdtZFHu+X2PovGbPXDiMzKl+U1wqPEwCXiIaIZDDOZOxesLFfL0P83Jb6CNiltDgKJotQc0gl8xAsvE0IDz3ZwgELfQgeIswqeOh99/QuEQlPSAAABIhJREFUFsyoAkfPCKNR294YVXp7fPMZ+82b+q0fPNhFxJFeT5BvGh8iko+enp85avioNnfEtni1rSlaNtL4oDmMD8AhPBE8/jHwQhVD9wkWvlikBSP/0D16FoAdY4l+0FILwRAUkC7qQi9pgWCQwmFhdHvy+dj43aoywMUJlm+mLs964JYBHfuaEr6J0Rs1IBS8AjAAB/PBgTkhIwSNCW8X3/Sb5g/w0Dhy/Ab8ZMgQFaz66DRmn+jGx3sltkj5asrzpAaT2yn4k09JEBpMfXh/UZiYTO95I/L9IyVSHARYLYxljpWWtR/OYBhIkhDX2gfiTjQBlP+BF8ztLlhynwJtPISXlTYrAc7RC0KxJ4BxwbTjBaY+nkeoh3HSG4ACWMFiP8EEjpSEo9haSfy2QXjMa/+cvhrvg0PCglzdsYMW8yhUfyIiwYcT+rBXV7e5XHBxWrGjckiB19moDIo03j7na5eYGSIucpgIDqIfHWChPUo8o32DCKCpzqtURmr1P7eNa7y13w09XqWX0RAE1dupH6KaMWsnf7y53dEzJ54stVTcU+yyd7Tg2Hk52saaH21DDmCjlCtHBEd1PKLxo6SH6Zhgx3hFYDx1GJFoBbYGrbbEIGnOmzTaIxjLHexSwacZG9OtICggKf76U0q1uRq4fGqKxVU5qcRh718seCNssJB7uOEW40FjQ/yN4OBCAL9xBoT/xj0sZFgcjOp6D7sUExa5Jykq+s2vJj33FW8GTNNvog40y4R2sx59tMLjbo8KsJFDS8s/TsILtIkzhWPBujV3zf/9gNnHxlkdNabeDpkJMVkGymVwQvlaVfVvrF3Y8UxxTle9TroJQVs6ny4rEpITmnaxed0Son+Q/0/5wdLLZzvFNihzOpyHGsfEH+/cqtORVUOfOB1oLKXahAbuXcM3TL8p2HDzwfJFXp7p9Y82984pyE02GAwdL1sqWoAgjE1jEjva3E5IDXQeEF22lJ0oV7zWznFJlYUVJXtjImMPtWrY6Ai8B3zcGA0TF+aS8xqAqJ6FTMAChQfyw0TPiIArKgpvvVRe3DbMaOyxJ/+idHN847Y2xRtd5nLIThAzaSi01xRvCNOEa3Xlh8vyT/dq0EK+WFr4c+voBLsqSQdbN2ha1LB9m7Pm3oO5N261dgkPq4gjcJ/PFbm0+4O6jXn77cQzuYdvvVxZ1DnCFHbDibKimBtiGrSGq3i0TfaQBiCGSTpvZtGlY4mRMSoOph/DnsnJxlHxh3t0v/EwXi1e9RoPf1AMPzUHWgStX/n5B/9VTSz+Kz2pTSi16/i6pCSy4OJFURerEfo06+po6YvuVzubCMIQM6pZhmpnuJbrq8Hy3oULMVZvEcLBMBaeoBMfad4Nv4IkmG1TOiOuGbl6X4MUC1JD1S2CCQTLXV2qblb7cV5VDR/s+sp4/vIlpfDSZaEczxJMBrVHpy7iw7feE2q8AjVwxpDCUsiQQkhahzgCGembq6wb0wVYyTlTq/6M4Nh98agRb9RV7JUaoX2zcIXM2dXzVP2GhE8dx1/5QZI7aJv/H+y6kJy2/hwbAAAAAElFTkSuQmCC"},{"id":"USGS-Scanned_Topographic","name":"USGS Topographic Maps","type":"tms","template":"https://caltopo.s3.amazonaws.com/topo/{zoom}/{x}/{y}.png","scaleExtent":[0,16],"polygon":[[[-55.9959409871,52.00107125754],[-112.02896100663,52.00107125754],[-112.03994733476,56.01308253302],[-120.0049439862,56.00592357111],[-120.01711631014,60.01202439709],[-132.00196823895,60.00239237126],[-132.01208445818,63.00193292546],[-133.96882922149,63.00050478005],[-133.97240257168,63.9922484722],[-141.04429430438,63.98726254018],[-141.06879354491,69.92045693283],[-156.24893170976,71.51583202984],[-160.44570905351,70.83527373985],[-167.08145124101,68.42906280103],[-164.08218366288,67.03913532024],[-169.01504499101,65.68268604273],[-166.57608014726,64.50777504773],[-161.82998639726,64.0500622981],[-165.08193952226,63.26030016403],[-168.02627545976,59.7862264253],[-162.53311139726,59.73089435789],[-162.35733014726,58.55904663221],[-157.83096295976,58.31752983705],[-158.00674420976,57.52404350658],[-168.22402936601,53.51022153947],[-166.55410749101,53.14277307072],[-158.77578717851,54.88541314654],[-158.68240338944,55.7496444805],[-156.55105573319,56.00847621073],[-156.15554792069,56.7746616888],[-154.70535260819,56.14336689443],[-152.07412702226,57.37034511851],[-151.62918073319,58.22653323066],[-152.00820905351,58.98055685754],[-145.98770124101,60.24740887373],[-140.38467389726,59.48634241018],[-136.53945905351,57.80610084736],[-133.79287702226,54.83482554482],[-133.33145124101,53.14277307072],[-131.46377545976,51.69838238021],[-128.52493268632,51.74602265442],[-129.79385358476,50.90159054062],[-124.56436139726,47.49785657441],[-124.03701764726,45.48627362525],[-124.69619733476,42.90428451679],[-124.49844342851,40.3414647251],[-122.80654889726,37.53929308709],[-119.99404889726,33.37084692374],[-117.24746686601,32.54119524801],[-111.13906842851,31.19770451575],[-106.70059186601,31.23528720858],[-103.20693952226,28.64618215851],[-101.84463483476,29.81580068657],[-99.20791608476,26.28743998885],[-96.79092389726,25.75431753335],[-96.92275983476,27.96911213371],[-93.47305280351,29.68226300815],[-88.94668561601,28.87732407469],[-88.61709577226,30.17736083469],[-86.20010358476,30.3671253082],[-84.96963483476,29.43379356715],[-84.09072858476,30.06332630046],[-82.97012311601,28.95425748047],[-82.97012311601,27.26823750278],[-81.25625592851,25.07956298739],[-82.09121686601,24.5610471236],[-80.06973249101,24.76073298597],[-79.85000592851,27.11188091684],[-81.27822858476,30.70777424386],[-78.99307233476,33.20554049136],[-75.03799420976,35.59830000028],[-75.85098249101,37.2425160052],[-73.74160749101,40.4585957587],[-69.89639264726,41.60224497127],[-70.68740827226,43.17628724449],[-66.93008405351,44.69516042167],[-66.53457624101,43.08006996122],[-64.20547467851,43.35229243812],[-59.50332624101,45.73220792131],[-59.51431256913,46.24761804024],[-60.00320417069,46.25901313529],[-59.99221784257,47.24505773341],[-59.00894147538,47.23759898478],[-58.99795514726,47.50266941922],[-56.51504499101,47.50266941922],[-56.52603131913,46.74770404019],[-53.99917585038,46.74770404019],[-53.97720319413,46.48358117386],[-52.49404889726,46.46354265729],[-52.50503522538,48.75360583388],[-52.99667340898,48.75451123442],[-53.01315290116,49.99551104004],[-55.00167829179,50.00610367548],[-55.03738385819,53.74720613495],[-56.00418073319,53.73421061801],[-55.9959409871,52.00107125754]],[[-59.50126630448,43.7495431608],[-60.50239545487,43.7495431608],[-60.50239545487,43.99999882251],[-59.99839765214,43.99999882251],[-59.99839765214,44.2494016836],[-59.50126630448,44.2494016836],[-59.50126630448,43.7495431608]],[[-155.95024091386,20.49523373356],[-157.3267518687,20.49153389084],[-157.32902509355,21.23181053727],[-155.95251413871,21.23549220541],[-155.95024091386,20.49523373356]],[[-157.64488202714,21.24845058596],[-158.28534362719,21.24673774522],[-158.28689557694,21.7499618541],[-157.6464339769,21.75166877943],[-157.64488202714,21.24845058596]],[[-156.12602216386,20.32469602374],[-154.7461696274,20.3284088686],[-154.74174482011,18.87578125335],[-156.12159735656,18.87203473488],[-156.12602216386,20.32469602374]],[[-159.29077130937,22.24504086823],[-159.2892966564,21.76857042389],[-160.28916841131,21.76590592196],[-160.29064306428,22.24238530626],[-159.29077130937,22.24504086823]]],"terms_url":"https://caltopo.com/","terms_text":"© Caltopo","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAA2CAYAAACCwNb3AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAcppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGFpbnQuTkVUIHYzLjMwPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgofPyfmAABAAElEQVR4AeW9B4AURfY/Xt3TEzdHYMk5I7KICKILhwE8DCe7eieiomRByRmGjKCAIHhgjl+PNUc4UVZEggKSdsmwsMuyOU0O3f3/vJqZZcPMgnfeHf5/BbMz3V3hVdVL9erVa6HNhEciCxS7VtBJKvsDJlWUxCjFa8tdk+6oD/zU1ZOMhyttYXYmK1EhMlbgfnudQWgd161y8+jRnhDZgt6+ZdIkY0nU71N/ijlFyjBneAMNTX/3lSZH8k51u1RR0i3KFHZTvrUy9qy13NWvVbtebkWJ0agq0yusdH9+zv5u0Ym4YgfCw0wHY6Lj93zw5Iw8fz2C2WymjxKo91q/U8xmwGOugufhDUuaFpcV9XJ53T0kSUo+VFooJIaHxSXGxifbnE4lwWASL5cUHRA1YmmEVn/Crsjfx2gjD26f+dzFQJu16wzcv4ZvAWU1AXhUVRWGvrSwvdNj73uxorhNpGTofryiSDIJGm2HpOZ9y1wOKdxoYnar9ezlyuKzbSITbSqTf0mMitvfuVW7febBwyp5mykpEtuxQ2aCUIMOhEaTH/qkQHEOEgShHE801wDg9ZNFELwiY4lhXmFWxbqPVzIgFquGWARoYCJ6zRsz/YS9eLmLqYUCE6SanVDQcZHZFK/S0RQZ0a998p2bhz+zK3XLFk16WppcM2+tK3+bzab9dXqx4lmuoH7G6yc8BHQ8+euXPUq3sNiI/sm33vniX54MVr/AUlNFlp4uY+LFQatn/i2nrDDV7XGnWEQlslRRmFslcFSmEUQmW0DSCtEDkkYjaMIjQP4K00sSixAEZnSzypjwyB/ijNEv7pix8jvKVpv46F49qQY8dzw3+eFiS8UTZV5H3wqmGB3AFpfHwzSihsn4ZjYrANMIzOtVWUSEwACHiH9hBItXsbUMiz5q0Bs3Z8x68U3gG8Etms1mhs81EW31+Xj2/15u8ePJQ0MdLucjFtndzY4JLGcKk71eJogiU1VUSeMjAEhZVpnBIIh6I3IoLAxwxSoahju5kTrjBze37v76xuHjj9M4ABaCqQoeSRZZnKLX6ZnL24CJAo29L+HndZcCsAUAAzKoJgNTLe5wfivPUgdqS14ev2cTvOF2o1b02uwNGQawdhIxcEzxMlmnZS7Fq6/9POS1v02rIKN+CVTmRP0BMK7QFq9f9TJFr2Gq7KlbPzghZhP/0+XUF+c/0Hn248suM1eHMsDE3G7MiwAABUUEshHXlAVZNRjCNRgS0Dv+qEx1uj2YTgFI62Iuqk9kkTkO75A4Z+WQ3gvHfZPcptPYDY88fSGllkQI2jcqj7aIWAmeboDnEuAplQGLB/3i8DBFgzyyCiIBxmvDIjWEWVoUdCqKrLhloKnMLCB2C+ik0F7SO8yl7d1yxrBpf14zd/6Xk5Z8CGRk1RE/KCy4mboltYpZ3WoeN/Orw7tm54tyhMXtBAFgFDAk6LpK40NEIAJ+ozFSQ2oApgMPMbser0Izb0MZG7IC6CaS4J5qObFv8i2Lx5n3zNu4mIgjNRVtod8EC8ZTcDMvuqUyD2c/CrCOPsSKrrdPADb/N6bPrQHsXoFh1pCSImqTEItISuL38Ac4RdOH/tII1voncJYjYAyIO0uU8dqSv01JEWWR1w9YatVN17x+jLEqY9xFQvZqyYeMKk1wj/mjVu68fPrjLE9lhzK73Su4vV5R0CjAP8J9AKZKQF2S9JJTVQQXUNCFqaLfdI+eUz4BhVBEofIlDoey11Yw6LvMX44OXD+vawbUJSKSahDU/AkuCrygcVP7LRy7cmfB6Y+PeiwdSh12r+hRILUFFXjI4ZH97eFbAxgg4RRmg5Sja9As2uDwiETAohe6sNPpzVbtHQ8VZ6cPWDZpM4idIz4RSU0grlz5iCNdNn/9bpOOsx//6ainbPlppyXCYnd60EMZRKFidDSB8aE2MRoamx8eECvzKIpI8ND4YCwlEWJGVETF63B7TtnKxJ/txYtuXTx+16a8/SYiDhAK56KiqoCSiFOAygHSH+OjchkAWAXZi5HHyISUIIFhJlGPAaREncVFrQ/q5GPgyxMo9tu+r1a/jyHVrRMzRjdbTRu2MdNbOa3Abge5qSAMkRaGErQoTO5vSxy7feWADCAXj+w+4ayIyL6UvWfEO2vbE5EQ4gWpVWBmM2+uzYxhG391l00rsNkUjax4UQ1xDvpw6glSNuQtVEhcAcQrSBr0Ldda6f3eljdyyJrZu8+rqoFU2QBSVq8kQBxzvtjS+Lv9Px077i7vU2FzeCTONJgWCE9S6zfBQ51DGXw4zmslUaPKDrd7l62g73tvvfVPah+wUBbQXSCBewV+Xu/fYAHgCYpXlURje8HA+sY32U0wpw5sRZ2qJ/072F9PtVWPfnv9yaNGaVFc6b1o/OwigzLW5XC4RfB+dIS4YNBEtykLvmX6gMNx1SFoZtykjJhcHRiJ+4xiDTt5/uR7lDc9jasRVF31RDih3r746XVnRPdYq9XhAa8lFSWkFYeLs2rw0PxcQazqVft+Q0hLQEqJWR2ub0rO9Rr13OS36AmQ0pfhyl/BDyP7cu/WLT9WXI4CIC6wE60XyB0KYYn7EQw0NvTxDeeVSmv/ghILDsJ0zOlxHbQW9U1Z9sxMypMCY8CVfpCAv84TAQiAsQT0irHGMKlnWMLOlHY9222d9+LnGF0xMJjXeTeqgZelObB5s2fYaytuyLWVLbVUWsHSBHDF0HMBJIdAgaKmyiIYhEbVajRQHkRonRwhqlVe5yfK6Zhbdp/3WJL/+tKSxygDIUEgI36T2iU//PKSBy54LROY3eEFonGJEchT+5sQELCAW3lFgoVggiYlKqqCZTDRVfAEBGfIqpdtDvdhW3HavS/MHoacih8GXigA213PTZ+RLTj7QP11oz19KMLw4wcWBjLDarIKHhLG0A5kiJlQRblE0Yii1upwsNPlhdOe/eSN6AxI2dB6aPB+/c/ukjLrRSdVrSS1l6K8rWIbzPxm6soX9hNEWFQxsznkZPzPgL5Kw+lZmTzHpYL853NVF1mDvNDdSaIETdBPyIwgJphMrLFoLHeJ4gmnwJwGr9zIpnrbX3TbgZIYI6gdwSog8QrVRJPnsLELxbljcPkWkKBK6hJCULn9F08ty3ZZAI8kAJEJ7+okugkVX1Z1oqa9IYpFSYZLxbLnrB4EHmEQOhaqzuhsu4X0GBkaJBkT6iQiEp0gSYXWCnZe0ax87cSJz57s0AFrelriMJYBK+XML9+L2fLj19MrXDbAI0qygppqQRTQr/AE+CFqWmjDWEPJdKlYkc/qYTvQKkrHE15rtBPGDqjaCqmstesg4GA6BCEJHouWxR7OPDwCt1Zf9wTCRRwZDmVFig8Ll9rronZ1btd95Oa/jT5BnRq1aZQ26XKSbE5Pp8s/VjKnu4dvfqHdj2cPDmQON1iqJjRxQGUgztwjIrG8fVKLme2bdP/IPGRIMXV4h6pKmzetGCiez1ybrdrai2ReCWGy53q3W2aXHRW9xr2zoc3GR8efMUP6ZkA4E4H0mDd6WKantAMQ2wOWGxQejp/YTGBaQXNrRMN9PVp0WnRrcv+daZ07WwmeV7Zvb7Dn3C99ThfmLdxrKejqcblBJCwokcCiAQOf4AGDaPRO+ktpKP5a/4ULNSn4kQFt4fDpQ8PKtUoscwIeFfDUIg5k4wnEoej1Ok0PU/zOlo2bzRvcJeXQsN69+R7H6q1bY7cf3fH40aILz+W4HbQmA20HrwmcRayElatMqHwQFfsIhNokkiUqp8/1kgJSA7JY6qCPltvEN5n15eRlq34CgKS7D/lrkmrub/Zt6AUsQfUC/5/u3W+v/1LZpbuLNaThk/SAhTRIIh3aq8hi1/D40sE33d5zyb3Dz1fLJvQHp8X11nFbNqTsPPLz6WPW0nDsitCOSR10AoSwP4leu8Sky2X5t6HcmQw/cVCdHtU93eXlZlsxlEhGHV4Rmy3Jxrivds3f+OddKLeOCvvaU0cOHFiA35/Qp8u8EVuOqRWpqkcmGIMyZEgGsczlZOWSnbj2ayBUhaX6YL9YVDiwFGZrvi4LNbywNGNRpmkhmf6xZ8HGh/egkvfxQaL+q5PvvrsU36v/vHZ2sT3/3FslDrsCI1ZQgqXRYW4vc0ieHpM/fb2pCAEKoSzTfhN2d1RYKtB5iPI6I0vN/ZcStc23m2A4iQsPl26LarL7js59uhFxEAijNm3SHkg6RcThXfPrjugR61bcAAoH+MHVgf8S2GjmGkat1iTLLvdtFtlDa6ughekmdhOUOKhVLWOT5hBxtDA/biCu72+Q97vJpFTjxrTx+S1ik9ZqDUZSF4Lit695US2DmeNs8eVmNDbG2BKukt29fOZNpR5nV5j98TS4moaMqEKR2jJ95Z9vuYsQGnsUZh2pRfhJ1dNuvTho3QS+1zPqnqFPddSGV0Ifk3xlqUTNhA5AiiisyGG/cdimpY3wVGHpTF51eFsYiLkP9AcMTjWDUrXiGAQY6BVNG63JPbB///H0KNVcAx5mVvlYSV8+u+ztFrqwnxnUMN/WSLWK/D99kkWQKwXFcPLsmTaiVhCiI8LDWJTRqDcYjRLp+DDaY59FhewTvFho1ZrSupX+nncg/kCrEKeiIHU0xSm3xbecuXPu+r7rh43JIqlh3mGWuBsIdswnvb2+Z/rnW07+cPEILfBY8ujRQTnUFfiC4uCVx/+1X1fALHDbmnOFiMvwugAAYiIAKRrbHs0aNfyccjzOWriBhJhLv8AHc7jlFt9eUKwx8uNGfPtBqWaBqVkvYQd251miKbwjPfnm4Bd8YByCc+glEYxegCG2ZpGqKzzwag0G1jKu4Wvmu/5S2NmcqktPM7uxzggUUQm2byaud9Gzib0HV0YbIzYzgx5snv7XTT6kZF6HRjWWlFfcHMhx+Kefm5TarTGcJEMxP5IeOokl6iP+uWHgYyUshUnp5hrwMLNgVoA7vI/Nw+K+MWFfHAyAxq9O4p3ARnIxNkTPFeVqxJYxCa8PiG258e5mXV9INias6qgJ/6CjIfJiQ/jTKFBtZOw0wJ6GvTj/ZNSp8ve5QdDjQ7wLi9Bw7W3RTffendy32yfPLnmOWiDCOHDKJzWIWw1dM3fZtuO//LLbXZJ41mUnNypGUoW+r+uETmKfkLqLPn0RD4W4DXFIrA5JItRJWhp94EDTsJiKOwbegVUvYwsWLKjTz/TULXzCW7VsfSFaZ6gAvRHL5WzdP7ZcRPGGaaihKlR63MStGXszmyOuxW4Dt5ZDwsIBVGVNM1HPGic2+YiKduqUGhTp6VkCK/IhocC2x3DvHp+ptDY8PpgE1QmI7R7XjVSWUqGlvJlghHWa1jscPfjtGn+wZlc1ko5l2yy/0IPkdj5CqJEJF60GlnFYPFpxN8QSRkbl/hTBYVHVaK2O9WzV8SZp9+z1L9eubMOOHeGf/rqtTwerdVShtvLBLNkmwRUFLEmEiST4RNau47dck+kSSp7CtDqpoSxYbghLmLdtzpoXd6ISkhqtBg5UzP3TSIdlE7as63X7kgmvHnaWdK2wV3r0hjCtEXtP5b+lwesk78nLeczicQFryD2i/kRbfY3j24dERtTBicZ8d1pph1mPncL1TbASkYcBV5+q187VL1XQFNtt8NPgyUPqzKtb3msDoy2KYlfA7+JVvRzNE0hbjBT1l4Y9dv+B1x6fxNJTU0OCnsJSlAwstVtFJOWcLy30YIqx5Q3vD/ytqpegpiswYbvi1f5QcM4VeJZVVuAppi6AcOpwhECmQHHsi9OtgOdEtcf+n6n4TmftW7TzZlcUsSK53KtIZDEOUrOqeuxeWSorq9BLJAYzs4tE9mYGLXb5BIzv35+sEbSj+M9Rb6+92XQua062UDmk2GmHSijC2hp60whlri0BLr9hwItFkBRpNIpNmWFr1+ZtR30wfm4OVZICuzwGWD2QtpnDdf+auQt2HP3VfMyONZfMPEbRoDqAFxoRmiClIL5Y/P51+kfr8cCRgSboCr7UBhXrDzwUWYndEvvl1+mReG6vnSdwHdh1LrDZ5YjYKKY4XXpy3KudYMORnGDMsaIp6pz/4eG9+9s7ZW9DqHtggcH1fWCgQlt8UcawrP5CSyIu0EzovQ7zArPKzIyVll7OpU6YwsM0vt29uv3FxolUqZfYPbFN+37lhwlrC0g6/0WIL/RO8GIN1zYirttl5MnIMAfN2TkrSyU7p+xwZju8biZEROrDMa5ByANbRbIUGxnGEqIidFImTI1UI9QWcep7mzpl5meHaXUaTaw+qqilLuGSefgT+/D43j+vmzv0QkHeO0edZQb4FcENglwgqOS/lrA5S3tbCqzUUhuN0ZNgjHp69/yXNtPOQDJMt61iBip+T1p15JurO2deOPvmpwWnejJs5EgaiXQSER1VI/SRLNotlnOsCeKL9a9B9x8sVW3M4JKtMYq+tWsoTABnAIoI3suy0/TrmaMDANn7PTfztZbPelcNVJ+aJbBBbbq+ZxO9hyEGHGguCIUAqWUlXK8z7uT7SKijwFYebyfsBcLj75VFUrX6AQtOF8CZk6kH+G1zCtxSMqrlqPXTj9w3J9/pjck5+LzV6w6DixgEGCRILajgOgDlmpliJOPeQC1hBqNY7oF/F19ehaQUDbwzWaFUOYg299Y+8EQ51kA1PHKpPtzjI7/m0w25D/T7y7LOTIgig5RaXZoFGobjI9xOw+Ni476Q0jYt7X+5KO+xtnOHJ+tVsVO54hG14DqwbFX8qjMU9l024ecoKfyDLycu+XDjkR+/e/3Dd77b7yi+UXV7PXzjhtTKkLAHWrzyzRUBAIbdGikcA9CM6bcP7N570rqHxx5DLhFOa0JR1kY1fbRPavRbOnHCP7N+eeECc2NmvF6dRivCIQ6dVaRWkdGsbXiDtU927vViGvsHRiGDS5orrV2HvzBWWHLwdHO/uyt/PLWvCEgZidUC+lRN9fCDTrNKfodFLuzwFufM26+q6T0FwROQFv5svi+fmiW8P3H+SzXu13NBKizt5oczqYeH89N6fI4g7eJFibWIiLOSKTUF/yDh66ndx6CxX0P8a2Z9Gas/C7jkd4lvarPmnYTnLVc2gnJ7SDVohKL3hNcerj/00wzUM+vdkn1kLq9S1fx1cwJh6ZnuT9Iz51Rvr77f0i/ZJ5df0Mk3K9hdhTM9VQKbGlZUWimKuZ1RTHC2jWKlj7SfOfzEt//8buT+RZt79F487h8XvZa0vLJyGdwc2g55btafiIZASVho4D9O2TRmOkfTsPgpe+etfzmLveWXGmUkNUiXVB9at7j1iaLzmw/biwZUum1ctQNBCm7sBxhNRrGLLvJs15btR77+2JQd26hp4kpXLCl057pNosYne59o2dLZc9HYo8xjaa14sLdHDpNBEje5Kqr3nNveYeayKaQp3E9uNVwF9e9+VyumEvGc2x4jhtbHcVQCxwBo4VqU5fN2/i7/vNbJFVUSI6FmUxXhjsysLvtBai+hU2aojNXA8f0kWKnN+mDKwPNUrDexrpFhemK9OnY6fvzyubI8puJQmIA9iBCsmPxVXV52Xq2Y2X3+qIOHFm1OB+1K5hSzAslB+FQjEQFa8trVCwvBOiQpSZZK3A6rip1VLHHsilZnitPpJZOXlUZodBcahkcVV7isF42SvvsFe2nDS56SH/ssHL9+97wND/35hZn5Lpd7YokHqijWAzjAQ6ZhLqQDfJATBawMWPPBWwfre0HRRhtNYpKo294uvuXITyeZswG5iMETMy5jrTHaJwFSVkwcvzc3a/UFwaNDx2F4kDRwV1YVDXbT4U6UHNVk7UvTV81sKwguNipZyzbtJ6K+5smqMVr/44sG+oi9Ea6y+y0uaDb1SGLghuR0ueTtpefu67vw6S3PjJjxWFrTpo5giOD3SbuqND2wGZ1PSefqVK+Yhk22l+fysxN1MArZCDTMLzOCITpNOv86KBV3iV6vnjLqEnLQQumbCSiexJl3pFXcMO/Jg2Cof1Khc+BuHYODPy9QTFQqvR4x2162ZfDKaU9/PX3VBjPWI34JSTK7Cj8y+KG6DH/R0F+kR4pGYmfovU6vM7XWhh3pG9vs2ZQuPTpmLX+rx/dz1t15YNHrT+2a/3LPnOf/0aR1XEIXtOKcuOkF85dTVjzTPizhTzeYYs4nhIdpZQ3cjqHPYQwhJEio0F4VllmgDxCHGGnSa1vrwktuDEscn7X0rTuIOAh4UqkweOAYGd5H317Vsvu8kd8eqix66YLHphPdMihE1Higk5hMBm1yWMLJGxu2uHHbjOcnEXGQmwkrgwfvdUMcVXMQetRrZenYqPFXTRRoBIoXi5HQFELFyKcJ29vyT47C1FWbF2U++eoLf4KG4+Vckk42htorCA0NVrU+xDHpjB3JggUOFxQILtowuZGilrU2RIZC1Ppa+k3PiGlSAb3W8EGEXgeEAlaFSIS/tHdHG9zlXhc7UJn3Um/z6A9mbX8rjtRHFFNRX9B1VYgqq25LDqZGNtaHsWbayAV7zBsWna16xAdKYljNsEzfJtT/jZpPa+jpw7ZsCB+1aUXU5tEzv9+Wn991yRsr/tpEY32yzGnvbmFeg42GGDMaBmNIGCY0wRBxLjLC9O7tbZL/bv7LcBxJZQIAxiBnqOl+C9WdK6eN3Z15ZM1Z1a7HVr8Hbj4i7II43SSL7SJjWfuoRi+Pnbpi0mAQBhEWierNo7lzXQDl/K1e6cB//1dQ3KoJRrUsgyZM0D8//JljtywY8yFTHEMVl0Im0KDuJlQJ7ygdlsLRwV/chS0rsj3b+5jHru/TqtuS54ePLSS1hBAh4xq5NQfMLwTyLGXw5MOGNqFi0OQbXnj3gpmaAmMeNOfvcRN94IAM7nD723n7P55nEYVmIF5iuJxwgrVBzyBJ1AKrRS4yeh4q2Lat/4DlExd8N/PFTWAuJEWwxk2tcqEPVkfte1JnQ/SeyPCoWdtmrNxBD8nsa2gUA3WHU54HxMGwMNQ+vH6i2KTUIjRt1VkzPm08d0qj/Hc1bGjD16v0eeL1F5rm5l+68bylNAq2W2+rqDhvUmzMkXfGzj1LAFID5AZQBIL3D4A6/r2Xmu8/dXTzLxW5d5ZhrQFB5KFVlwdrDZPJKNxgiM7u1qrjqE2PPvvtF9Oe4wiAatQAEvQyjx5ThrPHp1/44O/cq9d/VBJ5rvsU3i9OZesZ69C8zYKi07ahZ9RyrQYjgEMM1cioZjf8RKKVVFE+VVEinjLpJ1hP7XtyyJqZyx59dvmKNB8iCECE3+T+X+ay+4REzeaqrgIAgUszA/uXmHFVXdf4g3N9c1qa+5aF4xYVOYteddnh9EgUUE8FEDOURVIdHs95wZnocAovd5r72JN3rZw5b9v0FVuhfgIJmcbcGQ4oQdYntauW9izeNInfhIhO7TQOHJ1vyCk7zp83rP1403155cUDxywa3T+3olS4ALNsg2MHNL0WjKqINoXtjo+I/eT9cfO2+yvVvDFiSg5+04enbP/3u+PmCeQ/FNdIJ6ePNnOzMj26Z83MUd9m7nvxlGw3wFTn1SFCCYIS0FxoEnRGlhzXbMP8KSun9REErmunpJhZRiYWhiCCOV+81XjfsV83HXCX3lMhO5fzpmLO0SSHYoE8y/X1pxNUS7P0xoipWXesmjolX/C8YLU5vHBO1F6tE9gE1GgkEBPU0CPuUlOmbFuSPWfEiLSXFi3d8vT81/k6JCUFC9WUoAvVK+PgEyFwhvSLqCtP6v7CBhi0AoPBRyB+4VM32+90hzNBMxPhgPhaz3kj0341Vtwpk886HW6qJ3FdDJIY/otKfrlVzteKPa2Vl77pYR71TZQhZtqOmc9hd8PMGKmlCzL4WfZQ1VFPObcpyuqME2a+CB7DXl7+4PS3lq3K8dpb5sOTEvv/IEuYfoG6uR4Hy1UdQEND94YVheNaz3jkwI3N2i77cLz5Y2pk5OZVD2c7Cg98+8yq09UaVbPNbzqzcWMLDu289vy0O3LKC6fvK7pwW7EDm4+QGhKOCUOzwqLIIPUNS8xp3bTF8DefmJaxdeoq7tJ+6nJSldS4dcnEB9L3fPfqKa89FuCzSFjEuF/zH2EfpNqg8J8+dUj8dtrzq29bMrHPLjX/QdnhcsMnTcdtXQHWXbscroHSeEqIICmywysf1ZS3ys8/8doN80c80alhm7n/N272D+aMjGtSu7Bg5LUFaYbf4mAgCzaKoePVI0Fo7ZCZWQ/UoVrw3Td37lyDs5uZ798dXe8YVrb/i1/O6rzNNR4VuyOqtj5JQrWhT3QYEschVTmnsoLl6G2Dmjosg25fOuHNbm1vnL4+bUQRqvcHhPAFafBBceWvBDEjcGpKT+eesVu3f7Pup0vHHz1vh/OGLHi02PsENKBHURuF8C4NdAa3Tqu7iGNblXbVo4nQSD1OluR9NHDZM1+2a9Pur0qlO8dl83zUY8EoS5Sg2WbXas7FR0brC4sKaQvjxkXzRtxazjwdc3G4B34/Xh1UCjc6gnMBmg7RcayhKfr5V2asmUuLcFprkJvJZh/hKrTo+ipj55oTtuJHi5028liwa416k12mg2Z/3ARjBk4ICWzn3HVDsbj8PEuqHFJpteE0G05Q1Yu2vj5jt500H5hbBLnIalOKdK5biy4ey+i9ZPwbKd37TFnx50fKSK0Adwpp0OC+v/UtvfkIKwzno5hJbwiVk86zh1xMX8sM+c/1UGsc/4Gf/JTh8rS0oj8tnX2zq+LCz7kaWzOsKMBEmO5qjfmf4ywahggHanJUm5RjcT+e/2vZ0LQX5y/b8syi5fWYzBkRCK9j+N+X3PfuZ+9vOuCqaICzwrIRZ3dcGHEEsdA2NUWwhobIH2D23ZwQ3XDv3U8MvZwmwMSINPOnbYk/HdjXqMBe8UR5acXrI/9y34jPM/akZJ069tkptXJhCaQCKyghxzjf1o0b1wocbMCJsOTSubUia2g0MhgKDndq1PaZd0ZN/6HtzLVVUiMg1R57ZdmT2zJ+WHPEUxkBdUzWI96RCwEt3NiCbaLXm3IJGNi2ySzzR0sgDuKafPd3r3nTvbctfvrVXTrvk16ckQC3plOG9bDsK72l/ShIHg04midPsUn5gvxE5U9bBz+wes7oTyYv/QxmMOCvr50rpa7tF5kkmUarKbBUuAut5eepVBbcN6pKQxUCN1ZaTXlwZoHKegC9wQFDL6iryvl/kJ9XpaKYUlt1OZj+zOIVuE3qMsfNDEhZ8q74bvSygtQNK2/OKTq/e6+jqKUKtRwqH/yPr96On1AomomKmETek4IlvKTo7LIBSyfe36lt14dfSht5nqtcteKqSbM+fitu/5nDz+/KPfn4ORu5/Ekeg06rcXghNySdlGyIq+zStO2Et0bOfNvfF/b6CL5sIS4ij+17F1ml6PPs6i1bjF9+uyNxDWIv4brfk68+f1tW7pkxFcw5yCZqoitxZsapk5heo9HpoB800Ohko1b/U1xY5GvfTF/1Nvdf8G3wMPNobsVQEOol8suff1z//cXjw3Os5RSSB3suGhGxq3CQQW+41ZhwuXPrlp9tYh8wMzZ2zGj4j5iAuLRW4ESyc95LT93/wsyzZ8oLlx2zlUp04g4UIiGCC+fj9fXPhwiQ97QtBX09izkaOMtzP+23ZMKyH+eun1O9nbr1hK6elAjEWRDOuu2Vq1aNJrcnhrquEEhmKgqnMxxxHGqL1CULDuzLExO8xsT1JY0Gu9RqKxQhAqkBDBmNUrBeSx8/PX+Hqnaas3jsO2c05UMLrdhEhusRtttCBpWoDgLGByYQHOpgGqXYavV+77T1unyo8vi9G+c/+Pm4RV8hL8frQBlp+6+73vmV2Qd5Ky0eHRzRPJD2cFoTm4RHiV0iGnwx4OYBo6b3vyefCsICpUlvlKcyn4WLryM3wcIFWzPLcbnEyWlpJFUuBCp/7ampO/F7J4VsuVSc0+d0fk4UNnLcjQzhUuPwuLJ2DRofWfXw6LOB/HQQ6tTly8RNgf2M3bl6zpD3f9y2+bTqaqg6XF69Ros4UAhvBXWsdUQ06xjd5I3RUyY8PURIslOwL5TjMAXq+6N9A354CkLb6i9oPp2yYvnYd9ftMJ469topT0WnChvWajh1CM5MQRSumqCjE4LpcAZdPldRouaHu2YPWD65+/ezVt9D7eDDibFmRVfwveZ9UCcQy4v16A0RCfFpc99rN+eBRw5hDwuWspqRJ+HcVMps8NaSVSdgDaWK1a4ePADTqnoN2KmEJ2rwlAG8IC+B/ohLhxypd6+c9vhlofiVw+4KCYGvEL0E0SYhRYOXrnkXIfywPBF0Gq/gOe4p0dsvyV8O37hkztvj5i7j6igObFEJKctaZvLCUcQAlcopexDkFYsKfYKla6M2z7w1bvYbW9kL1Z0HuQVqxpa3m2XmZD3icrvuenH+iKRchxXAwUQ873FNpNZ4IiI8Ymuflh2/Nj/wRDY1snRI2iV8VW250kXASY4lM23KELMmg2V4A/FwZ3y7JerggT2vZpZeHHrJSctv0aMXtBqXjHPbBkg1Y3Rej2YdR78yYsqXX05dzhehOCTDiQqZ/9CJ1C10wEseAi8Pm7gXBNN10Mpp888qebNPq07ovbKMdSGc2eDeU4PHBu82XK/BVrSqHdFDvpdzB6csfebrjDkvDiYi4RuLaWm+gldh9tDO4KSlyCYj9tJFIYEKBbNiIZPE1Wevl/ZzrglZqS70Gu6nAAIMgK5DJVov+ImbbZ2+6s2ZH723M/zEnjVnbaX35mNdCkqDFVDEfirWZVdJxGiwwajVCpJ8wVIu7C45v/S+tXNLPnt2ySZS6UhqSVhky3YEFHTKLm3DiEjWJTzhq3v63jZy0m0PkhjVpGAR73MD2UxqqHD3qqkrth3NmHpCtotONyxcZP3wi9IyWthLlrZRrvIhRaXFnsHPT3uvS8sb5q18cFjulPdevivfXlnx3sgZVd6aHP4DzJNxwHeufNn2j+P2Hz847ssdX0/K9FTGMI9X1mKMPThgROuNZmGRrH1kwlsjn3jq6bREBAhIYVLquC2qz3fHzKv7/82fzQe4SgGCIcI3j3tn9btJF86vPucoH5Jjo/Nh/LQnnWa/Kpl4oJoBaXSy0+k6oi0e9Kflk5d9N2v1bLawPxA4gYsNEIB/WRx8BGmaaVnghprsUOA++z9MnLjRPhlxVjz4yDn8vO/B9eb7z5fkrTzqKGvr4dFL+Lhdk7SFMqiBe6ByprhArbRY/566aUlm+ui5PHayZCcvKZwN6KpPqOjQoOmU9AmLXtvOXqwuNThnfnjtopt7zB/x+iHZ1km1Yv0lYi1AthOSjdxNhoYPo4x4rBVOh/qrYtX+Klsfz6soSRu6fuHQTs27Hs7c/dkbty8a34BpNf+AC8HppOg4I4hMLrNaYnCm//Z/7PzqT5dke2yx3Y44DdgSod10FQxBpxe6aSPzOzdpNeb9MXM/+3bGmurw+dQqEO/143Ly+2BPBklF9KvzwjTtxkcnn0Gt9963zjywSenltSfcFZ0RmhQaCc7ngC1x/K2nWTLjgtnoSysq5FOKOCv15cXb08fO+56fB4I6gRMOJLfqT5heLwxhdrfPalilEtQsRZIJxAbrSbUNT0gWEo1XJeaaVdV/RW4kFLIUah77aIL5U+T+9J4XZs44W3pp9gmPLRJ+fDIPrH0NahckLTRYrbdQcUsnLpx5B5vj7chrWmokGSJv0IfvfvCuB//ybG8ejUKE1PA7D/qkBiLNLd1bcHJWtgciTIbfuUarBdVp+cFlrhH4OoKR4T+gClIgEgrn6DmkFphckvC1Z89Xz0Ak3pVsfup5l1dYVuq1shOWQkhthZXhAIsVh16YCxJJ0DgwjIicx3TwKGZNEDmxbUTCG08O/NuzPIxLQGrAJR4iUDZ/9UbDvYcyE7cKwhGuMlw3fln1T+41P0V/MsF2Aojw2UTzdpTtAheKMZfUklUnZWc4XHMowNtVTcKQJPD706o5TguLz7+4CvUkY8eML2midXAf8SKuFlA4GLHxe+BBFAe4POCvH6QTWEHpcWCHifAWwsGrqhyqh/xJiUyqbv0uPwJrIOCsRAzlqykrnpvx7aa/h/34y+JKg3fCaUsZ9tkgTXhc4/qbBJFI4ADu0zpnixFznhqH3C+Kt7boOPnHBS/3JeIgvcvvPOgl58GHNiy6CQh9ZJ+tYFa2rVLVyFxs6UAc9XaTBpPy4DyYTo/gecdLCuT91twX+yG85gHzq1MHt+/doYGsec5jd2RX2KzYDoEQQCER0TjC4F/SQGeUmkv6gt7h8R8MaNejz46560YQcXD4xqXSbj93bhyx6flbv96/98KhoouPUtevHrSBcv0xkx8RZEIE6sH3s9b9/b6eKR1vj2i4tQGiTMLED74U+nRfoNeQJBKcEr3FXluPxzYvuxf3udyINYSDrZGtKpCz5jesRGBeAuYVgbK9tEaulbDBR3ewu5kt2Oz5WK6cZF7PGRUfGKpPJUo6B2EN6g/RQq36fuMlEQcxSFK7nrtjdMWBRa9O7JnU9s52hqhTEtatiLZIx06v2jZUUcnpdLIKr2Pq6t1bjNJrY2f/RLBwCrxMLue+g0p9lk1YvDv35FzspmMIFbdGo4H7Awb3NyZEH8f+oFa9VF4h2yLkpZ3mjtCuTHtyIaqZad7/xaIjew/0PF5woV3bqPi2JoMp+uDFcwd6tOhwqVF82+/XwCrGFyxwCUjBgqO6S/zN5vGL/3n2wNxcyBpJ8ZJ9+o8RtKHa+BVlZdXLaKplrfoZQARSu1Y+ODIXDwYNXTt39LGCi38/4ayEoiSA3YS25BCG4AAWy4HX65niy3/DJY+Ugqg2dh8NEImEwCNAi0PCDO/jqAs3LfqRytd89Bh9V6XUVMmTnu6Om/vUykK5YhpzQJSEiP9VVeZf/QFpi60Cj5ksdBlm8f/GzPkW6+aOt+CIRo7WOu5SZbkKAvDFC6vbA94qtCB4bOJMupY1+Xrnz0MkMpvBzYRczjkn+duLi5KPFWW/ftBa3M1ps9ELnOigAm1b/MuJFonQlcVyq022GGUziETIWvK62dyTnzTbiYp3Hq9W+6nA79TOukH9BgjffHxUzsjwwXf/i/OSzxbmvH7IXdLN5bLDumXQGplG4hQSKPdH+b6dAxpiqup04grWVqld9M6MdPVDWF0e2bRid/7JA9vKBU+j+iIrUq1YGsAM5mVFtoqe606f1k9s29Z1oPjiL6JWNxjnu9HOlaYCUPjuCMyBRfqlcgRg4CnoKoQTSqAcvjnqFLuslZIWR0mrPbiGn799bFApCIRgUOg4BNQ6gnV86npzznfOzOWl2LCGeZdi/gStm/qJMkIRwv5UOiz9xfSsoiri6L/kmYV78k/sP+Io6+a0O0lqgJiuvgBEnVdNBBAAE+FnJJ9V7AtwqOUNKjRwxqgoWMa6Ba0AxyMpvhJO4nuf3vJKy9uXPrNx36XT+4+6Ld1cDic24TUKLO6snP37QRsCKBH4DgpP/TeDDnh9RTIQ+A7Pqcmrf8gIUStxh0QgQpsJg/TvjZ55tH+rzilttOEUdoFiYoXsCp1hg64NhwRP84O7PmtJ1eKkOL0bCqWCF+N3cfANbkEsUdUnURlirPRdK9G9K5+YGICCcx2wEwWvuVbpmpdU5Fo+NUv5rzbDTEvShLYS0ieYVwxo1nF+NNR4jA9FwgiZoKpifBAFWfX2kGit8bfNS7tn5Z5/42d7QXebDS7nElRaQf23pEaw1olIMAmiy2b37NPkPX7nc5Oj/zlj9QMDVky596aFY17D+ZGPEsKj9uBo6fksp4PdGRkTVVZp61rutQ/YdvCH4Rc1Xi2kBkUFR9xYbI5gbZpoDGdt9XFlpCemJA1RM5gvnkCw9q/lHhkayKx8LXmr5yGWdfWEajHdsF7z/QEwibWI6j4EngEkAPm9GnUAkzGXWq0olCgLRw9Cz6DvcuSrgWtn1n/jIiL55Gnzqd6Lxj11TnG9objJgy5Inb4GCBAKuCbZ7I4WuHWiS2xjZ0nZRTCbGlX7cgf+whAFWwA5rnamW4G3dwUe+79rVuB/gREd5GCcVGrlDnH57BtrIg7lZ3+Bl/bE4Kg1SYE6c4Ib8C9XI+OMph3fzVo7EqJDxKfGVIBA6Fplo5j2wwmLFicvHH3zAcVzD/kB4m7QJQNwVCPDYKSJ0PaUbl3y9LifL5zYcAaWDZCMb61BC7n/UIK8hfFWoy2ptLh2qMr9nec9+eH3M18YetO8kbkXZfsbZxi8hUsraFfU/ZOlXEch9UsU7E86ET9Kg/NdoqD14ugu0+lYG0OEvY0xcdrWGS9spAHM8KuJQUEn9KtHvvsWoSJzgHMUl5f+Zo3SAGdnpKBNX7kJZRV7RuRgSvfKnY5bj7jKWuG1TGQjD56gDDSTTCwtuX+DA2zzeUw4hfas0xCIBIPE2J55G97qPPexRVleN+LKIpJ5ED8ljkHQsophPTx2+TwflUK7dT+PhYH8fE8wGDSAugIuPjDdc/z4TwTq49INbR+6kCsdt+b1KhDgz1pXePqgo/HWSayBq7KI38g01yEifzfUlCQzmKeZdUxq8Xz+ecs9l9xWKFLBw/7AmwTzIbGLzkpRPF5e9MQZOqiEN3lh3khqhGrE39a//4VFJIX613vwcpZMV9mDPcwjd/6y+JU3zy17W4h0CevaGcLcsUadsViUNSWykwMk0EsYdVpjpM4gtdSFFSXrY1endElu5ScOAqoO0lSH1IAOh8LBqsKQrOWke1rKTL6yQXXs6tUylpnB270hvmkPFUwJ3Cfo+Pluko6psHCNBHs231OoBFMCG1PcuE+vcKvx0eMcP0OM0MTwSPKgbUNlOnXqFLR+PFLJ2Q6zjoA08lcM71oEstXgplS+eiKmHkhNo+Id0UAYVINRCJ7AYwQVOnyUwdSL5zD7+h489793N1/nhFIp4IAqXoCqIKx9rbHh1yoYOliA1ePlpx3gbhSy0YwFCzjTS+7Z+xDOGkFQQqUMabOjakgLRegddLocHA0rKQVnmkPW/7s/ICLBTGjheerOclb26zZ/REG3xq0HvTt6zjPPvP/KsovFF+9xOO39LtrKowvwuq4GEVHaaJ3xAhag27u167ADgZqtXJmCWY9t2nTVoA2t4hsJ53LLKaYT73zwDgmKBpRr0uop/OU3Ph37KkSS7hu1M+UF8fQLa7ag+AVkBFfAe5FdjspThbknqH2OoDAaYY7hN11XHaLlMuQtK8a7MbIunee21fqhSUGBDHbSZb+gMdI5bh6lBvdqJgKQqsZ5f/h7mjgRNUhqdlxbcKYc0Ef7H9fpB6S6KEPquF3ODrtV1cgPstHaCERZs4Xf5wqijS8HaHyoldq10k0ZDKe5MTI+Cw/9a7La2fg1H0r8eqh7ivvzrZ9CXcqPxsE0eudMnXqxVgbfUtQ4nUmQaNr4CAVqCFr9f+amv0kdPCDcR9zOxPILzgN9Fo5b+OLfRprR4uv+D2+8hP/1/dlFXzgaPApHgzdvR8zVa5ggMOpDfJVIfAkDEGxGcVuwwD3/QllRO2oiA//qTT7kUO5fY47+Je9kJ4prC4wOKqi45QRrw0amiNIR9/3Z+slYM8P+hYBXwBKjCJp8BISYtTDcwr2/LTL9WL9pOIPX0ys6MelnRylhVFDMpeawtmHxiD/buXFzdhDXdHio3exHT4OIbyLswK06ayJflEcBUditjd9/86XmyHPCvHChYPbRGy5/j+QbjFvatBf3HbFpSq2kVeM100GrhkkWBILJbEMv2uHnXkIQbGCIvz+zT8L5IWgIcAIJQhzUDM708mPPyISQo//jxBEVG4rQl+WLeCPREVfpgi6zHzvdc+GYBzft3+9XdfxAwhpBrhHUB4aIkGSloOO35i1b6F7QlEKMGinCqM+MxFtNMSoSDUCwzBhEDb1yGd9/mfX16wlkwIC+H3KMkn0RDuFt40q1aBTivMSyA3NRowkgO2IPSyxSMh4fktTTTg8dbtchAZEKMflB4eEVgPhLsHgqtpT2oOsQC2OeFfDyvkIjuJXhveWc/fqe1P5LiyGN1+Vx4A3gVVb1MFF/hHbBOcrVLoFrwAnTiOi9iDXz8ZKcAZTli0Z5dQipZtGMwGXQcQk8DHwjEx+L4akTynASMAcEi0f0ysa6CTdpa14pl12RedkXOlCO1PT0oPNFhEzP9/16qElhZWUsFSUtJljC6l2maPQOj/tQ0MqCFfpP3wMCYSgkuHm5PMecFW3Ouys+XP/JhsNweFz9wJpZt9C5FRioPP5QqcqYj19OTF236HacXPxoy77PJhB8FBCsNpxAcD64bz4x/TT0+CxCALDsegZc9FwQnBG7Dx2ZSXWZM83YK6r5imIsxoWAtyflKagsm0NvJSIVhK6DJVotR2v1LCoi6rvAc63eeDYacaZI+wqVyIXEA4vKZUvpPWiXv9MwxbebXh3hBP/7OJS/vrK0W7a17EZy90WTQeEB4cCipLJYU1jhpEcmFKJtni9WF5YR53vJVV29ww8gHVByIMig02mfSrewsQwX9Jrj489KX8Kg2K4+AiJuHbqbV4r4c/WHkybeGJVNBAKLatCS/CZWdQVwIMipLHiUKkn/cbZUm6nRfG2ryNTT82MXztxXqgMsGFZOYHSzVvLXy8K1xmNBB7BW/v/aJV75RWtMLXRLuQTvCD/mKG2zszRn0vZLp3d//vN35xtPf+hAzLSH9yZNf/jA97/sOrszNzPjsOj4S5bbRtybZYQIXk3uB/Qca4vPyfqFQGBBCYTyYDYlJ4KeHyvNm4wACGlw0nf73TxwHI8jEqlogagvrN/ipz/YZy1qDsswArkER0i+GFQUbQNZ8uD1YB9SO5RwqOknHU0TEL86tvue+v6Cm5GpxXvBa2/xp+emrKC7GT5rHRblgMcHk8r3i/DsRE72y/mw+kGK0JH2oNXiPrR6iUVrTfs7C4IbUhlUythNbTvsivEiGJ8iY0svODrzPuKN58dsxS0HrJg0F8V8rj90pJc8Hoh4fYyKcKsKLpMGr3XnumRQkKh5X6q2hovQGX7G62qIf3CcDWSp/o3BgTu6W71QUTT2kb8v/RNbf8ZlDph6q83XnjXpjmkfvdn3YvHleRVWKxlTeJ+r13Xlt8pM0JQVJu64rgiEAKSRIFcJkDh2lkTFipfFWxAFPdNRHnEJGzdlzHtznuLpccphDS9wO1wqkDkSHq28cyGCNgTeDdGzWYdPuujCIUA9eD1l8ImikDv08tgSBKc4XHD2H7eteHbtpC2bunLQzKR9MPXVzN2xaX9fPLinedSBXZb8h+AsSJEx6hlw+LDptaxpZOzHLzz41AU/ArHnJy/PbKIPzwVq0e5CSKIlkCrsDnVXSc7UWxaPfRMB9rp8rZ7WgzgU+mQiEMbjr6xKgTXwp1/txX1w9loOtuinMaJe005iks7EmkQlfkb3Elhn1JMirfjr2OxYbfg38KCj29Co6iaaH6ynJBzgUg+V5i0euOzZdUu3v98AjIT7x2UQ8UI1RTYO1/gPXupx7+qZY6DQPKa4oL4GMUbUbcV3J8Jg3BpLQW7grhR8ttAIuiTh5brnnFZ2MPvkt/esnTV75idvtOA10Pig9LKdWxIeXDd37PeHf9px1mM3IrQSef8FrRIMEuSoSs2Z3jage999QsKUh74v0sj9/ZPsE4c++K6rvxLUAnSqKtAHNAR6fRwhntZk95qt6z5eyBHPNznBYKe+yX0Wj3t3t6XgERy2h5EodJA2ag97SWAlBrGLFg6zsnwEQZmsOrjdRGh17bJdlZGF8GeiDSdIFDJ2BE2+ejxq5+hEcUCnXt3XPzzmMLn3kAcDIRJUyJe/Ljo/RnDBxwPSM2gluEnrJqhM2JKWhFZaE4LySWdtslxA+Y1MbOiU1FZn8R4hsIqQxEF5dZAsbq9L7B3bpHj+hKmtB8e1rSQVJC09jcfRunet+bb9+ad+wJtwZRy58xlwqGCtBM4KR2xVjQg3io0UbWUDY9SvFYr7V6siu6IlSR+nDbuxyF7RDIH/WuYqTlYJB0BIWcxfcCmLccI5VlXzQPOuOz6ZuHgAmuPz1WbWsENnPNYbcN4YAx3axwwMT4HTK+LDG9gNYhh6JByrVBWLgak6k6jpeEaxhyEQBqQ2XpRbj68aYrZ4FBxd7W2Ie3Wv+eWR9XC9WiPyP76EqkEUzwmYSxlc0Y2gbCAIrBC7dJSX9Wpxw7SKrN1Dsf+ih0U3pGMftYfAU4KMwADH7IUaqGbd+MEwLCaYFXtyOIUGwgDKhiYOIDUoWPHow8J07WKTniPiYCkpEsyRfPFvhpWsSXzT5zuWFIw5rpRCm9AGNTtSdyAR0Bp6ixNLODSlwXv2WmMzqzUXuXQ+H/sEeG0zAtGERiIaKwT/9iZGRunaxCetJOJIgUqEfhDHl+mo6efPmnfetuTpr/KY6x7EbHaj/qAGEOLcdGbVYoOEZ/bIU17r7UzS3q7DNuM5sk/jKAOFMgUDASvD3i7WUqGIg/pXJ01oI0FdklvGN3qlqOTSSxWynWRJyCDpdJ6Dv+DJ6ZIP0wuftNquPoMiTQI24nEaAJoBnVkOKQRADKrX69a20UWpXTp1WkaOstedilVnoH6nGyAOHj5m7aOjL7dNaDw8zmAir28EsRHoBfNBk9/KIUka8F2EUBUgRohD60Ss8viE+wi2TmHUR3vl4FQuptPoeoc12IVXyfFFP/zKuOpC8JDE2/z4xLOtYxqtZGFGrKvx7okQsFAb9AgfmmewdpFWPTiAgLe9QBUFZ8TpwtCTT8QBu78b9kJdB130j+8+vWAV1ZlRzfuAog3SvQG9+o7qKoWDAas6vAKOjpEETaS/gGphmwPrx7gITo/HbXN5ELDBQ9cUGIHGDnSNmAzBJUfQiunm+jNEtMK3U1ZtaC6a9oMh6DDmQdyIr9TgU5ugmmt0FCgaY0MbrwwLKgoJIeClMqH5KbYAEB9b9SThxUM3JDWf/WrahPMpYB7/zxAIDSNHBizYP528bEvzsKhHm0RGwZKIE/kCYixhgK4Mdc1f4DqE7JQP465qwFZD4QyfASAi+LniCQ8z6nuExf3ytznDSWVgZp/J+Eo7/veZfDn9uRm3GhJ2MYNWh/pdYHFX8tQEhV8RYoIYiJY4TIAP9uvQRQAPqaZuvL5Y110fc/yhB1MHU0V+eHid/mswkRTJfOdf82IiYnonavRWnP/Q0viEgolapdcSEHFiCOk95siPw3S4Jq5OY3ctKZAL39Q9nih8Kv24qUWnv7ZkRhvsckRt9RIJ5UebPnhovgBHfeeXiHEAaCjTqhIRYdI1lcI2fPTMUjKGiBlgHv9PEQgNHsMxTbJqHZy/6d1bGnV4uEtYvJsjJikx8CMkXfa3DgrnzlizwHwKIw/eCI5VYKzRpO0Z1vC9d+ZvvnW00JMfDQVCVk0+hwWEEEDS2X+bNLCPMXGXZNDrQV2kTnnAmTlQ/rzX/EXw4AMKIjzBG4NVWYwIN+l6hifu6nfL0BvHd+5v9UeBqQ0PmEiGl8Zn54y1x/u17NI7OSKxGOs8Hb3MFdVymLiZ+JqhCZ6RKqNxJsIjKQ5tjd5hSBKpSqWjnfEUcPHXnpp8pkNis16djNEWhcQ3TmOhLCFvgK6CNxLiLuBH23yeiS68cE7VNDCaNLfFNH5u37xNT/NimEj6Js85qMkYJ+43r0IK/RE+ONgGONEDwE79AAP9DYmHxAenTB8/9x+De/yp9Y2aqNcaSHpZi4BgOJkHDz+qlN7XwieBVDBZDwLAAl3l31joYmowqWgfSEPSWaZhhk4RH2bSdtZFHu+X2PovGbPXDiMzKl+U1wqPEwCXiIaIZDDOZOxesLFfL0P83Jb6CNiltDgKJotQc0gl8xAsvE0IDz3ZwgELfQgeIswqeOh99/QuEQlPSAAABIhJREFUFsyoAkfPCKNR294YVXp7fPMZ+82b+q0fPNhFxJFeT5BvGh8iko+enp85avioNnfEtni1rSlaNtL4oDmMD8AhPBE8/jHwQhVD9wkWvlikBSP/0D16FoAdY4l+0FILwRAUkC7qQi9pgWCQwmFhdHvy+dj43aoywMUJlm+mLs964JYBHfuaEr6J0Rs1IBS8AjAAB/PBgTkhIwSNCW8X3/Sb5g/w0Dhy/Ab8ZMgQFaz66DRmn+jGx3sltkj5asrzpAaT2yn4k09JEBpMfXh/UZiYTO95I/L9IyVSHARYLYxljpWWtR/OYBhIkhDX2gfiTjQBlP+BF8ztLlhynwJtPISXlTYrAc7RC0KxJ4BxwbTjBaY+nkeoh3HSG4ACWMFiP8EEjpSEo9haSfy2QXjMa/+cvhrvg0PCglzdsYMW8yhUfyIiwYcT+rBXV7e5XHBxWrGjckiB19moDIo03j7na5eYGSIucpgIDqIfHWChPUo8o32DCKCpzqtURmr1P7eNa7y13w09XqWX0RAE1dupH6KaMWsnf7y53dEzJ54stVTcU+yyd7Tg2Hk52saaH21DDmCjlCtHBEd1PKLxo6SH6Zhgx3hFYDx1GJFoBbYGrbbEIGnOmzTaIxjLHexSwacZG9OtICggKf76U0q1uRq4fGqKxVU5qcRh718seCNssJB7uOEW40FjQ/yN4OBCAL9xBoT/xj0sZFgcjOp6D7sUExa5Jykq+s2vJj33FW8GTNNvog40y4R2sx59tMLjbo8KsJFDS8s/TsILtIkzhWPBujV3zf/9gNnHxlkdNabeDpkJMVkGymVwQvlaVfVvrF3Y8UxxTle9TroJQVs6ny4rEpITmnaxed0Son+Q/0/5wdLLZzvFNihzOpyHGsfEH+/cqtORVUOfOB1oLKXahAbuXcM3TL8p2HDzwfJFXp7p9Y82984pyE02GAwdL1sqWoAgjE1jEjva3E5IDXQeEF22lJ0oV7zWznFJlYUVJXtjImMPtWrY6Ai8B3zcGA0TF+aS8xqAqJ6FTMAChQfyw0TPiIArKgpvvVRe3DbMaOyxJ/+idHN847Y2xRtd5nLIThAzaSi01xRvCNOEa3Xlh8vyT/dq0EK+WFr4c+voBLsqSQdbN2ha1LB9m7Pm3oO5N261dgkPq4gjcJ/PFbm0+4O6jXn77cQzuYdvvVxZ1DnCFHbDibKimBtiGrSGq3i0TfaQBiCGSTpvZtGlY4mRMSoOph/DnsnJxlHxh3t0v/EwXi1e9RoPf1AMPzUHWgStX/n5B/9VTSz+Kz2pTSi16/i6pCSy4OJFURerEfo06+po6YvuVzubCMIQM6pZhmpnuJbrq8Hy3oULMVZvEcLBMBaeoBMfad4Nv4IkmG1TOiOuGbl6X4MUC1JD1S2CCQTLXV2qblb7cV5VDR/s+sp4/vIlpfDSZaEczxJMBrVHpy7iw7feE2q8AjVwxpDCUsiQQkhahzgCGembq6wb0wVYyTlTq/6M4Nh98agRb9RV7JUaoX2zcIXM2dXzVP2GhE8dx1/5QZI7aJv/H+y6kJy2/hwbAAAAAElFTkSuQmCC"},{"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}","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,"description":"Public domain street and address data from the San Juan County, WA. Updated at least quarterly."},{"id":"Vejmidte_Denmark","name":"Vejmidte","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","icon":"https://www.wien.gv.at/layout-a/logo/wappen-klein.gif"},{"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","icon":"https://www.wien.gv.at/layout-a/logo/wappen-klein.gif"},{"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","icon":"https://www.wien.gv.at/layout-a/logo/wappen-klein.gif"}];
18636
18637 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":["name","highway"],"geometry":["point","vertex","line","area"],"tags":{"highway":"*"},"searchable":false,"name":"Highway"},"place":{"fields":["name","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"],"fields":["name"],"tags":{"junction":"roundabout"},"name":"Roundabout","searchable":false},"waterway":{"fields":["name","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":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"cable_car"},"name":"Cable Car"},"aerialway/chair_lift":{"geometry":["line"],"fields":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"chair_lift"},"name":"Chair Lift"},"aerialway/drag_lift":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"drag_lift"},"name":"Drag Lift"},"aerialway/gondola":{"geometry":["line"],"fields":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"gondola"},"name":"Gondola"},"aerialway/goods":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"goods"},"name":"Goods Aerialway"},"aerialway/magic_carpet":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"magic_carpet"},"name":"Magic Carpet Lift"},"aerialway/mixed_lift":{"geometry":["line"],"fields":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"mixed_lift"},"name":"Mixed Lift"},"aerialway/platter":{"geometry":["line"],"terms":["button lift","poma lift"],"fields":["name","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":["name","aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"rope_tow"},"name":"Rope Tow Lift"},"aerialway/station":{"icon":"aerialway","geometry":["point","vertex","area"],"fields":["aerialway/access","aerialway/summer/access","elevation","building_area"],"tags":{"aerialway":"station"},"name":"Aerialway Station"},"aerialway/t-bar":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration"],"terms":["tbar"],"tags":{"aerialway":"t-bar"},"name":"T-bar Lift"},"aeroway/aerodrome":{"icon":"airport","geometry":["point","area"],"fields":["name","iata","icao","operator","internet_access","internet_access/fee","internet_access/ssid"],"terms":["airplane","airport","aerodrome"],"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_aeroway_gate"],"tags":{"aeroway":"gate"},"name":"Airport Gate"},"aeroway/hangar":{"geometry":["area"],"fields":["name","building_area"],"tags":{"aeroway":"hangar"},"name":"Hangar"},"aeroway/helipad":{"icon":"heliport","geometry":["point","area"],"fields":["ref"],"terms":["helicopter","helipad","heliport"],"tags":{"aeroway":"helipad"},"name":"Helipad"},"aeroway/runway":{"geometry":["line","area"],"terms":["landing strip"],"fields":["ref_runway","surface","length","width"],"tags":{"aeroway":"runway"},"name":"Runway"},"aeroway/taxiway":{"geometry":["line"],"fields":["ref_taxiway","surface"],"tags":{"aeroway":"taxiway"},"name":"Taxiway"},"aeroway/terminal":{"icon":"airport","geometry":["point","area"],"terms":["airport","aerodrome"],"fields":["name","operator","building_area"],"tags":{"aeroway":"terminal"},"name":"Airport Terminal"},"amenity/coworking_space":{"icon":"commercial","fields":["name","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"amenity":"coworking_space"},"name":"Coworking Space","searchable":false},"amenity/nursing_home":{"icon":"wheelchair","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"tags":{"amenity":"nursing_home"},"reference":{"key":"social_facility","value":"nursing_home"},"name":"Nursing Home","searchable":false},"amenity/register_office":{"icon":"town-hall","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"tags":{"amenity":"register_office"},"reference":{"key":"government","value":"register_office"},"name":"Register Office","searchable":false},"amenity/swimming_pool":{"icon":"swimming","geometry":["point","vertex","area"],"tags":{"amenity":"swimming_pool"},"reference":{"key":"leisure","value":"swimming_pool"},"name":"Swimming Pool","searchable":false},"amenity/animal_boarding":{"icon":"veterinary","fields":["name","operator","address","building_area","opening_hours","animal_boarding"],"geometry":["point","area"],"terms":["boarding","cat","dog","horse","kitten","pet boarding","pet care","pet hotel","puppy","reptile"],"tags":{"amenity":"animal_boarding"},"name":"Animal Boarding Facility"},"amenity/animal_breeding":{"icon":"veterinary","fields":["name","operator","address","building_area","opening_hours","animal_breeding"],"geometry":["point","area"],"terms":["breeding","bull","cat","cow","dog","horse","husbandry","kitten","livestock","pet breeding","puppy","reptile"],"tags":{"amenity":"animal_breeding"},"name":"Animal Breeding Facility"},"amenity/animal_shelter":{"icon":"veterinary","fields":["name","operator","address","building_area","opening_hours","animal_shelter"],"geometry":["point","area"],"terms":["adoption","aspca","cat","dog","horse","kitten","pet care","pet rescue","puppy","raptor","reptile","rescue","spca"],"tags":{"amenity":"animal_shelter"},"name":"Animal Shelter"},"amenity/arts_centre":{"icon":"theatre","fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["dive","beer","bier","booze"],"tags":{"amenity":"bar"},"name":"Bar"},"amenity/bbq":{"icon":"bbq","fields":["covered","fuel"],"geometry":["point"],"terms":["bbq","grill"],"tags":{"amenity":"bbq"},"name":"Barbecue/Grill"},"amenity/bench":{"icon":"poi-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":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"tags":{"amenity":"biergarten"},"terms":["beer","bier","booze"],"name":"Beer Garden"},"amenity/boat_rental":{"fields":["name","operator"],"geometry":["point","area"],"tags":{"amenity":"boat_rental"},"name":"Boat Rental"},"amenity/bureau_de_change":{"icon":"bank","fields":["name","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":["name","building_area","operator","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"amenity":"bus_station"},"name":"Bus Station"},"amenity/cafe":{"icon":"cafe","fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["bistro","coffee","tea"],"tags":{"amenity":"cafe"},"name":"Cafe"},"amenity/car_rental":{"icon":"car","fields":["name","operator"],"geometry":["point","area"],"tags":{"amenity":"car_rental"},"name":"Car Rental"},"amenity/car_sharing":{"icon":"car","fields":["name","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":{"icon":"poi-dice","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["daycare","orphanage","playgroup"],"tags":{"amenity":"childcare"},"name":"Nursery/Childcare"},"amenity/cinema":{"icon":"cinema","fields":["name","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":["name","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medical","urgentcare"],"tags":{"amenity":"clinic"},"name":"Clinic"},"amenity/clock":{"icon":"poi-clock","fields":["name","support","display","visibility","date"],"geometry":["point","vertex"],"tags":{"amenity":"clock"},"name":"Clock"},"amenity/college":{"icon":"college","fields":["name","operator","address","internet_access","internet_access/ssid"],"geometry":["point","area"],"terms":["university"],"tags":{"amenity":"college"},"name":"College Grounds"},"amenity/community_centre":{"icon":"town-hall","fields":["name","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":["name","operator","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"courthouse"},"name":"Courthouse"},"amenity/crematorium":{"icon":"cemetery","fields":["name","website","phone","opening_hours","wheelchair"],"geometry":["area","point"],"tags":{"amenity":"crematorium"},"terms":["cemetery","funeral"],"name":"Crematorium"},"amenity/dentist":{"icon":"dentist","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["tooth","teeth"],"tags":{"amenity":"dentist"},"name":"Dentist"},"amenity/doctors":{"icon":"hospital","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medic*","physician"],"tags":{"amenity":"doctors"},"name":"Doctor"},"amenity/dojo":{"icon":"pitch","fields":["name","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":"drinking-water","geometry":["point"],"tags":{"amenity":"drinking_water"},"terms":["fountain","potable"],"name":"Drinking Water"},"amenity/driving_school":{"icon":"car","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"driving_school"},"name":"Driving School"},"amenity/embassy":{"icon":"embassy","fields":["name","country","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"embassy"},"name":"Embassy"},"amenity/fast_food":{"icon":"fast-food","fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"geometry":["point","area"],"tags":{"amenity":"fast_food"},"terms":["restaurant","takeaway"],"name":"Fast Food"},"amenity/ferry_terminal":{"icon":"ferry","fields":["name","network","operator","address","building_area"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"ferry_terminal"},"name":"Ferry Terminal"},"amenity/fire_station":{"icon":"fire-station","fields":["name","operator","address","building_area"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"fire_station"},"name":"Fire Station"},"amenity/food_court":{"icon":"restaurant","fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["fast food","restaurant","food"],"tags":{"amenity":"food_court"},"name":"Food Court"},"amenity/fountain":{"icon":"poi-fountain","geometry":["point","area"],"tags":{"amenity":"fountain"},"name":"Fountain"},"amenity/fuel":{"icon":"fuel","fields":["name","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":["name","operator","address","emergency"],"geometry":["point","area"],"terms":["clinic","doctor","emergency room","health","infirmary","institution","sanatorium","sanitarium","sick","surgery","ward"],"tags":{"amenity":"hospital"},"name":"Hospital Grounds"},"amenity/hunting_stand":{"icon":"poi-binoculars","geometry":["point","vertex","area"],"terms":["game","gun","lookout","rifle","shoot*","wild","watch"],"tags":{"amenity":"hunting_stand"},"name":"Hunting Stand"},"amenity/ice_cream":{"icon":"ice-cream","fields":["name","address","building_area","opening_hours","takeaway","delivery","outdoor_seating"],"geometry":["point","area"],"terms":["gelato","sorbet","sherbet","frozen","yogurt"],"tags":{"amenity":"ice_cream"},"name":"Ice Cream Shop"},"amenity/internet_cafe":{"icon":"poi-mast","fields":["name","operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["cybercafe","taxiphone","teleboutique","coffee","cafe","net","lanhouse"],"tags":{"amenity":"internet_cafe"},"name":"Internet Cafe"},"amenity/kindergarten":{"icon":"school","fields":["name","operator","address"],"geometry":["point","area"],"terms":["kindergarden","pre-school"],"tags":{"amenity":"kindergarten"},"name":"Preschool/Kindergarten Grounds"},"amenity/library":{"icon":"library","fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["book"],"tags":{"amenity":"library"},"name":"Library"},"amenity/marketplace":{"icon":"shop","fields":["name","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":["name","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-alt1","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"},"matchScore":0.95,"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/pavilion":{"icon":"shelter","fields":["bin","bench"],"geometry":["point","vertex","area"],"tags":{"amenity":"shelter","shelter_type":"pavilion"},"name":"Pavilion"},"amenity/pharmacy":{"icon":"pharmacy","fields":["name","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":["name","religion","denomination","address","building_area","service_times"],"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":"buddhism","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["stupa","vihara","monastery","temple","pagoda","zendo","dojo"],"tags":{"amenity":"place_of_worship","religion":"buddhist"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Buddhist Temple"},"amenity/place_of_worship/christian":{"icon":"religious-christian","fields":["name","denomination","building_area","address","service_times"],"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"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Church"},"amenity/place_of_worship/hindu":{"icon":"poi-hinduist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["garbhargriha","mandu","puja","shrine","temple"],"tags":{"amenity":"place_of_worship","religion":"hindu"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Hindu Temple"},"amenity/place_of_worship/jewish":{"icon":"religious-jewish","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["jewish"],"tags":{"amenity":"place_of_worship","religion":"jewish"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Synagogue"},"amenity/place_of_worship/muslim":{"icon":"religious-muslim","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["muslim"],"tags":{"amenity":"place_of_worship","religion":"muslim"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Mosque"},"amenity/place_of_worship/shinto":{"icon":"poi-shintoist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["kami","torii"],"tags":{"amenity":"place_of_worship","religion":"shinto"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Shinto Shrine"},"amenity/place_of_worship/sikh":{"icon":"poi-sikhist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["gurudwara","temple"],"tags":{"amenity":"place_of_worship","religion":"sikh"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Sikh Temple"},"amenity/place_of_worship/taoist":{"icon":"poi-taoist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["daoist","monastery","temple"],"tags":{"amenity":"place_of_worship","religion":"taoist"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Taoist Temple"},"amenity/planetarium":{"icon":"museum","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["museum","astronomy","observatory"],"tags":{"amenity":"planetarium"},"name":"Planetarium"},"amenity/police":{"icon":"police","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["letter","mail"],"tags":{"amenity":"post_office"},"name":"Post Office"},"amenity/prison":{"icon":"prison","fields":["name","operator","address"],"geometry":["point","area"],"terms":["cell","jail"],"tags":{"amenity":"prison"},"name":"Prison Grounds"},"amenity/pub":{"icon":"beer","fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"tags":{"amenity":"pub"},"terms":["alcohol","drink","dive","beer","bier","booze"],"name":"Pub"},"amenity/public_bath":{"icon":"water","fields":["name","bath/type","bath/open_air","bath/sand_bath","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"public_bath"},"terms":["onsen","foot bath","hot springs"],"name":"Public Bath"},"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":["name","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":["name","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":"recycling","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"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":{"icon":"poi-storage-tank","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":["name","operator","address"],"geometry":["point","area"],"terms":["academy","elementary school","middle school","high school"],"tags":{"amenity":"school"},"name":"School Grounds"},"amenity/scrapyard":{"icon":"car","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["car","junk","metal","salvage","scrap","u-pull-it","vehicle","wreck","yard"],"tags":{"amenity":"scrapyard"},"reference":{"key":"industrial","value":"scrap_yard"},"name":"Scrap Yard"},"amenity/shelter":{"icon":"shelter","fields":["name","shelter_type","bin"],"geometry":["point","vertex","area"],"terms":["lean-to","gazebo","picnic"],"tags":{"amenity":"shelter"},"name":"Shelter"},"amenity/shower":{"icon":"water","fields":["operator","opening_hours","fee","supervised","building_area"],"geometry":["point","vertex","area"],"terms":["rain closet"],"tags":{"amenity":"shower"},"name":"Shower"},"amenity/social_facility":{"icon":"poi-social-facility","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility"},"name":"Social Facility"},"amenity/social_facility/food_bank":{"icon":"poi-social-facility","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility","social_facility":"food_bank"},"reference":{"key":"social_facility","value":"food_bank"},"name":"Food Bank"},"amenity/social_facility/group_home":{"icon":"wheelchair","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":["old","senior","living","care home","assisted living"],"tags":{"amenity":"social_facility","social_facility":"group_home","social_facility:for":"senior"},"reference":{"key":"social_facility","value":"group_home"},"name":"Elderly Group Home"},"amenity/social_facility/homeless_shelter":{"icon":"poi-social-facility","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["houseless","unhoused","displaced"],"tags":{"amenity":"social_facility","social_facility":"shelter","social_facility:for":"homeless"},"reference":{"key":"social_facility","value":"shelter"},"name":"Homeless Shelter"},"amenity/social_facility/nursing_home":{"icon":"wheelchair","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":["elderly","living","nursing","old","senior","assisted living"],"tags":{"amenity":"social_facility","social_facility":"nursing_home","social_facility:for":"senior"},"reference":{"key":"social_facility","value":"nursing_home"},"name":"Nursing Home"},"amenity/studio":{"icon":"karaoke","fields":["name","studio","address","building_area"],"geometry":["point","area"],"terms":["recording","radio","television"],"tags":{"amenity":"studio"},"name":"Studio"},"amenity/taxi":{"icon":"car","fields":["name","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":["name","operator","address","building_area"],"geometry":["point","area"],"terms":["theatre","performance","play","musical"],"tags":{"amenity":"theatre"},"name":"Theater"},"amenity/toilets":{"icon":"toilet","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":["name","operator","address","building_area"],"geometry":["point","area"],"terms":["village","city","government","courthouse","municipal"],"tags":{"amenity":"townhall"},"name":"Town Hall"},"amenity/university":{"icon":"college","fields":["name","operator","address","internet_access","internet_access/ssid"],"geometry":["point","area"],"terms":["college"],"tags":{"amenity":"university"},"name":"University Grounds"},"amenity/vending_machine":{"icon":"poi-vending-machine","fields":["vending","operator","payment_multi","currency_multi"],"geometry":["point"],"terms":[],"tags":{"amenity":"vending_machine"},"name":"Vending Machine"},"amenity/vending_machine/news_papers":{"icon":"poi-vending-machine","fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["newspaper"],"tags":{"amenity":"vending_machine","vending":"news_papers"},"reference":{"key":"vending","value":"newspapers"},"name":"Newspaper Vending Machine","searchable":false},"amenity/vending_machine/cigarettes":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["cigarette"],"tags":{"amenity":"vending_machine","vending":"cigarettes"},"reference":{"key":"vending","value":"cigarettes"},"name":"Cigarette Vending Machine"},"amenity/vending_machine/condoms":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["condom"],"tags":{"amenity":"vending_machine","vending":"condoms"},"reference":{"key":"vending","value":"condoms"},"name":"Condom Vending Machine"},"amenity/vending_machine/drinks":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["drink","soda","beverage","juice","pop"],"tags":{"amenity":"vending_machine","vending":"drinks"},"reference":{"key":"vending","value":"drinks"},"name":"Drink Vending Machine"},"amenity/vending_machine/excrement_bags":{"icon":"poi-vending-machine","fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["excrement bags","poop","dog","animal"],"tags":{"amenity":"vending_machine","vending":"excrement_bags"},"reference":{"key":"vending","value":"excrement_bags"},"name":"Excrement Bag Vending Machine"},"amenity/vending_machine/newspapers":{"icon":"poi-vending-machine","fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["newspaper"],"tags":{"amenity":"vending_machine","vending":"newspapers"},"reference":{"key":"vending","value":"newspapers"},"name":"Newspaper Vending Machine"},"amenity/vending_machine/parcel_pickup_dropoff":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parcel","mail","pickup"],"tags":{"amenity":"vending_machine","vending":"parcel_pickup;parcel_mail_in"},"reference":{"key":"vending","value":"parcel_pickup;parcel_mail_in"},"name":"Parcel Pickup/Dropoff Vending Machine"},"amenity/vending_machine/parking_tickets":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parking","ticket"],"tags":{"amenity":"vending_machine","vending":"parking_tickets"},"reference":{"key":"vending","value":"parking_tickets"},"matchScore":0.94,"name":"Parking Ticket Vending Machine"},"amenity/vending_machine/public_transport_tickets":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["bus","train","ferry","rail","ticket","transportation"],"tags":{"amenity":"vending_machine","vending":"public_transport_tickets"},"reference":{"key":"vending","value":"public_transport_tickets"},"name":"Transit Ticket Vending Machine"},"amenity/vending_machine/sweets":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["candy","gum","chip","pretzel","cookie","cracker"],"tags":{"amenity":"vending_machine","vending":"sweets"},"reference":{"key":"vending","value":"sweets"},"name":"Snack Vending Machine"},"amenity/veterinary":{"icon":"veterinary","fields":["name","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":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["dump","garbage","recycling","rubbish","scrap","trash"],"tags":{"amenity":"waste_transfer_station"},"name":"Waste Transfer Station"},"amenity/waste/dog_excrement":{"icon":"waste-basket","fields":["collection_times"],"geometry":["point","vertex","area"],"tags":{"amenity":"waste_basket","waste":"dog_excrement"},"reference":{"key":"waste","value":"dog_excrement"},"terms":["bin","garbage","rubbish","litter","trash","poo","dog"],"name":"Dog Excrement Bin"},"amenity/water_point":{"icon":"drinking-water","geometry":["area","vertex","point"],"tags":{"amenity":"water_point"},"name":"RV Drinking Water"},"amenity/watering_place":{"icon":"drinking-water","geometry":["area","vertex","point"],"tags":{"amenity":"watering_place"},"name":"Animal Watering Place"},"area":{"name":"Area","fields":["name"],"tags":{"area":"yes"},"geometry":["area"],"matchScore":0.1},"area/highway":{"fields":["name","area/highway"],"geometry":["area"],"tags":{"area:highway":"*"},"name":"Road Surface"},"attraction/amusement_ride":{"icon":"amusement-park","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","carnival ride"],"tags":{"attraction":"amusement_ride"},"name":"Amusement Ride"},"attraction/animal":{"icon":"zoo","fields":["name","operator"],"geometry":["point","area"],"terms":["zoo","theme park","animal park","lion","tiger","bear"],"tags":{"attraction":"animal"},"name":"Animal"},"attraction/big_wheel":{"icon":"amusement-park","fields":["name","operator","height","opening_hours"],"geometry":["point"],"terms":["ferris wheel","theme park","amusement ride"],"tags":{"attraction":"big_wheel"},"name":"Big Wheel"},"attraction/bumper_car":{"icon":"car","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","dodgem cars","autoscooter"],"tags":{"attraction":"bumper_car"},"name":"Bumper Car"},"attraction/bungee_jumping":{"icon":"pitch","fields":["name","operator","height","opening_hours"],"geometry":["point","area"],"terms":["theme park","bungy jumping","jumping platform"],"tags":{"attraction":"bungee_jumping"},"name":"Bungee Jumping"},"attraction/carousel":{"icon":"horse-riding","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","roundabout","merry-go-round","galloper","jumper","horseabout","flying horses"],"tags":{"attraction":"carousel"},"name":"Carousel"},"attraction/dark_ride":{"icon":"rail-metro","fields":["name","operator","opening_hours"],"geometry":["point","line","area"],"terms":["theme park","ghost train"],"tags":{"attraction":"dark_ride"},"name":"Dark Ride"},"attraction/drop_tower":{"icon":"poi-tower","fields":["name","operator","height","opening_hours"],"geometry":["point","area"],"terms":["theme park","amusement ride","gondola","tower","big drop"],"tags":{"attraction":"drop_tower"},"name":"Drop Tower"},"attraction/pirate_ship":{"icon":"amusement-park","fields":["name","operator","opening_hours"],"geometry":["point"],"terms":["theme park","carnival ride","amusement ride"],"tags":{"attraction":"pirate_ship"},"name":"Pirate Ship"},"attraction/river_rafting":{"icon":"ferry","fields":["name","operator","opening_hours"],"geometry":["point","line"],"terms":["theme park","aquatic park","water park","rafting simulator","river rafting ride","river rapids ride"],"tags":{"attraction":"river_rafting"},"name":"River Rafting"},"attraction/roller_coaster":{"icon":"amusement-park","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","amusement ride"],"tags":{"attraction":"roller_coaster"},"name":"Roller Coaster"},"attraction/train":{"icon":"rail","fields":["name","operator","fee","opening_hours"],"geometry":["point","line"],"terms":["theme park","rackless train","road train","Tschu-Tschu train","dotto train","park train"],"tags":{"attraction":"train"},"name":"Tourist Train"},"attraction/water_slide":{"icon":"swimming","fields":["name","operator","opening_hours"],"geometry":["line","area"],"terms":["theme park","aquatic park","water park","flumes","water chutes","hydroslides"],"tags":{"attraction":"water_slide"},"name":"Water Slide"},"barrier":{"icon":"roadblock","geometry":["point","vertex","line","area"],"tags":{"barrier":"*"},"fields":["barrier"],"name":"Barrier","matchScore":0.4},"barrier/entrance":{"icon":"entrance-alt1","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/border_control":{"icon":"roadblock","fields":["access","building_area"],"geometry":["vertex","area"],"tags":{"barrier":"border_control"},"name":"Border Control"},"barrier/cattle_grid":{"icon":"barrier","geometry":["vertex"],"tags":{"barrier":"cattle_grid"},"name":"Cattle Grid"},"barrier/city_wall":{"icon":"barrier","fields":["height"],"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","matchScore":0.25},"barrier/fence":{"icon":"fence","fields":["fence_type","height"],"geometry":["line"],"tags":{"barrier":"fence"},"name":"Fence","matchScore":0.25},"barrier/gate":{"icon":"barrier","fields":["access"],"geometry":["point","vertex","line"],"tags":{"barrier":"gate"},"name":"Gate"},"barrier/hedge":{"fields":["height"],"geometry":["line","area"],"tags":{"barrier":"hedge"},"name":"Hedge","matchScore":0.25},"barrier/kissing_gate":{"icon":"barrier","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","building_area"],"geometry":["vertex","area"],"tags":{"barrier":"toll_booth"},"name":"Toll Booth"},"barrier/wall":{"icon":"barrier","fields":["wall","height"],"geometry":["line","area"],"tags":{"barrier":"wall"},"name":"Wall","matchScore":0.25},"boundary/administrative":{"name":"Administrative Boundary","geometry":["line"],"tags":{"boundary":"administrative"},"fields":["name","admin_level"]},"building":{"icon":"home","fields":["name","building","levels","address"],"geometry":["point","area"],"tags":{"building":"*"},"matchScore":0.6,"terms":[],"name":"Building"},"building/bunker":{"fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"bunker"},"matchScore":0.5,"name":"Bunker","searchable":false},"building/entrance":{"icon":"entrance-alt1","geometry":["vertex"],"tags":{"building":"entrance"},"name":"Entrance/Exit","searchable":false},"building/train_station":{"icon":"building","fields":["name","address","levels"],"geometry":["point","vertex","area"],"tags":{"building":"train_station"},"matchScore":0.5,"name":"Train Station","searchable":false},"building/apartments":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"apartments"},"matchScore":0.5,"name":"Apartments"},"building/barn":{"icon":"farm","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"barn"},"matchScore":0.5,"name":"Barn"},"building/cabin":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"cabin"},"matchScore":0.5,"name":"Cabin"},"building/cathedral":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"cathedral"},"matchScore":0.5,"name":"Cathedral Building"},"building/chapel":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"chapel"},"matchScore":0.5,"name":"Chapel Building"},"building/church":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"church"},"matchScore":0.5,"name":"Church Building"},"building/college":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"terms":["university"],"tags":{"building":"college"},"matchScore":0.5,"name":"College Building"},"building/commercial":{"icon":"commercial","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"commercial"},"matchScore":0.5,"name":"Commercial Building"},"building/construction":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"construction"},"matchScore":0.5,"name":"Building Under Construction"},"building/detached":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"detached"},"terms":["home","single","family","residence","dwelling"],"matchScore":0.5,"name":"Detached House"},"building/dormitory":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"dormitory"},"matchScore":0.5,"name":"Dormitory"},"building/garage":{"icon":"warehouse","fields":["name","capacity"],"geometry":["area"],"tags":{"building":"garage"},"matchScore":0.5,"name":"Garage"},"building/garages":{"icon":"warehouse","fields":["name","capacity"],"geometry":["area"],"tags":{"building":"garages"},"matchScore":0.5,"name":"Garages"},"building/greenhouse":{"icon":"garden-center","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"greenhouse"},"matchScore":0.5,"name":"Greenhouse"},"building/hospital":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"hospital"},"matchScore":0.5,"name":"Hospital Building"},"building/hotel":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"hotel"},"matchScore":0.5,"name":"Hotel Building"},"building/house":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"house"},"terms":["home","family","residence","dwelling"],"matchScore":0.5,"name":"House"},"building/hut":{"geometry":["area"],"fields":["name"],"tags":{"building":"hut"},"matchScore":0.5,"name":"Hut"},"building/industrial":{"icon":"industry","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"industrial"},"matchScore":0.5,"name":"Industrial Building"},"building/kindergarten":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"terms":["kindergarden","pre-school"],"tags":{"building":"kindergarten"},"matchScore":0.5,"name":"Preschool/Kindergarten Building"},"building/public":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"public"},"matchScore":0.5,"name":"Public Building"},"building/residential":{"icon":"residential-community","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"residential"},"matchScore":0.5,"name":"Residential Building"},"building/retail":{"icon":"commercial","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"retail"},"matchScore":0.5,"name":"Retail Building"},"building/roof":{"icon":"shelter","fields":["name","address"],"geometry":["area"],"tags":{"building":"roof"},"matchScore":0.5,"name":"Roof"},"building/school":{"icon":"building","fields":["name","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":"home","fields":["name","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":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"shed"},"matchScore":0.5,"name":"Shed"},"building/stable":{"icon":"horse-riding","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"stable"},"matchScore":0.5,"name":"Stable"},"building/static_caravan":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"static_caravan"},"matchScore":0.5,"name":"Static Mobile Home"},"building/terrace":{"icon":"building","fields":["name","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":["name","address","levels"],"geometry":["area"],"terms":["college"],"tags":{"building":"university"},"matchScore":0.5,"name":"University Building"},"building/warehouse":{"icon":"warehouse","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"warehouse"},"matchScore":0.5,"name":"Warehouse"},"camp_site/camp_pitch":{"icon":"campsite","fields":["name","ref"],"geometry":["point","area"],"terms":["tent","rv"],"tags":{"camp_site":"camp_pitch"},"name":"Camp Pitch"},"club":{"icon":"heart","fields":["name","club","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"club":"*"},"terms":["social"],"name":"Club"},"craft":{"icon":"poi-tool","fields":["name","craft","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"*"},"terms":[],"name":"Craft"},"craft/jeweler":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"jeweler"},"reference":{"key":"shop","value":"jewelry"},"name":"Jeweler","searchable":false},"craft/locksmith":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"locksmith"},"reference":{"key":"shop","value":"locksmith"},"name":"Locksmith","searchable":false},"craft/optician":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"optician"},"reference":{"key":"shop","value":"optician"},"name":"Optician","searchable":false},"craft/tailor":{"icon":"clothing-store","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"craft":"tailor"},"reference":{"key":"shop","value":"tailor"},"name":"Tailor","searchable":false},"craft/basket_maker":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"basket_maker"},"name":"Basket Maker"},"craft/beekeeper":{"icon":"farm","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"beekeeper"},"name":"Beekeeper"},"craft/blacksmith":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"blacksmith"},"name":"Blacksmith"},"craft/boatbuilder":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"boatbuilder"},"name":"Boat Builder"},"craft/bookbinder":{"icon":"library","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["book repair"],"tags":{"craft":"bookbinder"},"name":"Bookbinder"},"craft/brewery":{"icon":"poi-storage-tank","fields":["name","operator","address","building_area","opening_hours","product"],"geometry":["point","area"],"terms":["alcohol","beer","beverage","bier","booze","cider"],"tags":{"craft":"brewery"},"name":"Brewery"},"craft/carpenter":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["woodworker"],"tags":{"craft":"carpenter"},"name":"Carpenter"},"craft/carpet_layer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"carpet_layer"},"name":"Carpet Layer"},"craft/caterer":{"icon":"restaurant","fields":["name","cuisine","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"caterer"},"name":"Caterer"},"craft/clockmaker":{"icon":"poi-clock","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"clockmaker"},"name":"Clockmaker"},"craft/confectionery":{"icon":"bakery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sweets","candy"],"tags":{"craft":"confectionery"},"name":"Confectionery"},"craft/distillery":{"icon":"poi-storage-tank","fields":["name","operator","address","building_area","opening_hours","product"],"geometry":["point","area"],"terms":["alcohol","beverage","bourbon","booze","brandy","gin","hooch","liquor","mezcal","moonshine","rum","scotch","spirits","still","tequila","vodka","whiskey","whisky"],"tags":{"craft":"distillery"},"name":"Distillery"},"craft/dressmaker":{"icon":"clothing-store","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["seamstress"],"tags":{"craft":"dressmaker"},"name":"Dressmaker"},"craft/electrician":{"icon":"poi-power","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["power","wire"],"tags":{"craft":"electrician"},"name":"Electrician"},"craft/electronics_repair":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"electronics_repair"},"name":"Electronics Repair Shop"},"craft/gardener":{"icon":"garden","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscaper","grounds keeper"],"tags":{"craft":"gardener"},"name":"Gardener"},"craft/glaziery":{"icon":"fire-station","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"handicraft"},"name":"Handicraft"},"craft/hvac":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["heat*","vent*","air conditioning"],"tags":{"craft":"hvac"},"name":"HVAC"},"craft/insulator":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"insulation"},"name":"Insulator"},"craft/key_cutter":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"key_cutter"},"name":"Key Cutter"},"craft/metal_construction":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"metal_construction"},"name":"Metal Construction"},"craft/painter":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"painter"},"name":"Painter"},"craft/photographer":{"icon":"attraction","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"photographer"},"name":"Photographer"},"craft/photographic_laboratory":{"icon":"attraction","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["film"],"tags":{"craft":"photographic_laboratory"},"name":"Photographic Laboratory"},"craft/plasterer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"plasterer"},"name":"Plasterer"},"craft/plumber":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["pipe"],"tags":{"craft":"plumber"},"name":"Plumber"},"craft/pottery":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ceramic"],"tags":{"craft":"pottery"},"name":"Pottery"},"craft/rigger":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"rigger"},"name":"Rigger"},"craft/roofer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"roofer"},"name":"Roofer"},"craft/saddler":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"saddler"},"name":"Saddler"},"craft/sailmaker":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sailmaker"},"name":"Sailmaker"},"craft/sawmill":{"icon":"logging","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lumber"],"tags":{"craft":"sawmill"},"name":"Sawmill"},"craft/scaffolder":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"scaffolder"},"name":"Scaffolder"},"craft/sculpter":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sculpter"},"name":"Sculpter"},"craft/shoemaker":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cobbler"],"tags":{"craft":"shoemaker"},"name":"Shoemaker"},"craft/stonemason":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["masonry"],"tags":{"craft":"stonemason"},"name":"Stonemason"},"craft/sweep":{"icon":"poi-chimney","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sweep"},"name":"Chimney Sweep"},"craft/tiler":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tiler"},"name":"Tiler"},"craft/tinsmith":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tinsmith"},"name":"Tinsmith"},"craft/upholsterer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"upholsterer"},"name":"Upholsterer"},"craft/watchmaker":{"icon":"poi-clock","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"watchmaker"},"name":"Watchmaker"},"craft/window_construction":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["glass"],"tags":{"craft":"window_construction"},"name":"Window Construction"},"craft/winery":{"icon":"alcohol-shop","fields":["name","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":["name","operator","building_area","address"],"geometry":["point","area"],"terms":["EMS","EMT","rescue"],"tags":{"emergency":"ambulance_station"},"name":"Ambulance Station"},"emergency/defibrillator":{"icon":"defibrillator","fields":["access","opening_hours","indoor","phone"],"geometry":["point"],"terms":["AED"],"tags":{"emergency":"defibrillator"},"name":"Defibrillator"},"emergency/fire_hydrant":{"icon":"poi-fire-hydrant","fields":["fire_hydrant/type","fire_hydrant/position","ref","operator"],"geometry":["point","vertex"],"terms":["fire plug"],"tags":{"emergency":"fire_hydrant"},"name":"Fire Hydrant"},"emergency/life_ring":{"icon":"circle-stroked","fields":["ref","operator"],"geometry":["point","vertex"],"terms":["life buoy","kisby ring","kisbie ring","perry buoy"],"tags":{"emergency":"life_ring"},"name":"Life Ring"},"emergency/phone":{"icon":"emergency-phone","fields":["operator"],"geometry":["point","vertex"],"tags":{"emergency":"phone"},"name":"Emergency Phone"},"entrance":{"icon":"entrance-alt1","geometry":["vertex"],"tags":{"entrance":"*"},"fields":["entrance","access_simple","address"],"name":"Entrance/Exit"},"footway/crossing":{"fields":["name","crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing"},"reference":{"key":"footway","value":"crossing"},"terms":[],"name":"Street Crossing"},"footway/crosswalk":{"icon":"highway-footway","fields":["name","crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra"},"reference":{"key":"highway","value":"crossing"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"footway/sidewalk":{"icon":"highway-footway","fields":["name","surface","lit","width","structure","access"],"geometry":["line"],"tags":{"highway":"footway","footway":"sidewalk"},"reference":{"key":"footway","value":"sidewalk"},"terms":[],"name":"Sidewalk"},"ford":{"geometry":["vertex"],"tags":{"ford":"yes"},"name":"Ford"},"golf/bunker":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"bunker","natural":"sand"},"terms":["hazard","bunker"],"reference":{"key":"golf","value":"bunker"},"name":"Sand Trap"},"golf/fairway":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"fairway","landuse":"grass"},"reference":{"key":"golf","value":"fairway"},"name":"Fairway"},"golf/green":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"green","landuse":"grass","leisure":"pitch","sport":"golf"},"reference":{"key":"golf","value":"green"},"name":"Putting Green"},"golf/hole":{"icon":"golf","fields":["name","ref_golf_hole","par","handicap"],"geometry":["line"],"tags":{"golf":"hole"},"name":"Golf Hole"},"golf/lateral_water_hazard_area":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"lateral_water_hazard","natural":"water"},"reference":{"key":"golf","value":"lateral_water_hazard"},"name":"Lateral Water Hazard"},"golf/lateral_water_hazard_line":{"icon":"golf","fields":["name"],"geometry":["line"],"tags":{"golf":"lateral_water_hazard"},"name":"Lateral Water Hazard"},"golf/rough":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"rough","landuse":"grass"},"reference":{"key":"golf","value":"rough"},"name":"Rough"},"golf/tee":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"tee","landuse":"grass"},"terms":["teeing ground"],"reference":{"key":"golf","value":"tee"},"name":"Tee Box"},"golf/water_hazard_area":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"water_hazard","natural":"water"},"reference":{"key":"golf","value":"water_hazard"},"name":"Water Hazard"},"golf/water_hazard_line":{"icon":"golf","fields":["name"],"geometry":["line"],"tags":{"golf":"water_hazard"},"name":"Water Hazard"},"healthcare/blood_donation":{"icon":"blood-bank","fields":["name","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":["name","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":["name","network","operator","bench","shelter"],"geometry":["point","vertex"],"tags":{"highway":"bus_stop"},"terms":[],"name":"Bus Stop"},"highway/corridor":{"icon":"highway-footway","fields":["name","width","level","access_simple"],"geometry":["line"],"tags":{"highway":"corridor"},"terms":["gallery","hall","hallway","indoor","passage","passageway"],"name":"Indoor Corridor"},"highway/crossing":{"fields":["name","crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing"},"reference":{"key":"footway","value":"crossing"},"terms":[],"name":"Street Crossing"},"highway/crosswalk":{"icon":"poi-foot","fields":["name","crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","crossing":"zebra"},"reference":{"key":"highway","value":"crossing"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"highway/cycleway":{"icon":"highway-cycleway","fields":["name","oneway","surface","lit","width","structure","access"],"geometry":["line"],"tags":{"highway":"cycleway"},"terms":["bike"],"name":"Cycle Path"},"highway/elevator":{"icon":"poi-elevator","fields":["access_simple","opening_hours","maxweight","ref"],"geometry":["vertex"],"tags":{"highway":"elevator"},"terms":["lift"],"name":"Elevator"},"highway/footway":{"icon":"highway-footway","fields":["name","surface","lit","width","structure","access"],"geometry":["line","area"],"terms":["hike","hiking","trackway","trail","walk"],"tags":{"highway":"footway"},"name":"Foot Path"},"highway/give_way":{"icon":"poi-yield","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":["name","oneway","lanes","surface","structure","maxheight","access","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":{"icon":"poi-junction","geometry":["vertex"],"tags":{"highway":"motorway_junction"},"fields":["ref_highway_junction"],"name":"Motorway Junction / Exit"},"highway/motorway_link":{"icon":"highway-motorway-link","fields":["name","ref_road_number","oneway_yes","maxspeed","lanes","surface","structure","maxheight","access"],"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":["name","ref_road_number","oneway_yes","maxspeed","lanes","surface","structure","maxheight","toll","access"],"geometry":["line"],"tags":{"highway":"motorway"},"terms":["autobahn","expressway","freeway","highway","interstate","parkway","thruway","turnpike"],"name":"Motorway"},"highway/path":{"icon":"highway-path","fields":["name","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":["name","surface","lit","width","oneway","structure","access"],"geometry":["line","area"],"tags":{"highway":"pedestrian"},"terms":[],"name":"Pedestrian Street"},"highway/primary_link":{"icon":"highway-primary-link","fields":["name","oneway","maxspeed","lanes","surface","maxheight","ref_road_number","cycleway","structure","access"],"geometry":["line"],"tags":{"highway":"primary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Primary Link"},"highway/primary":{"icon":"highway-primary","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"primary"},"terms":[],"name":"Primary Road"},"highway/raceway":{"icon":"highway-unclassified","fields":["name","oneway","surface","sport_racing_motor","lit","width","lanes","structure"],"geometry":["point","line","area"],"tags":{"highway":"raceway"},"addTags":{"highway":"raceway","sport":"motor"},"terms":["auto*","formula one","kart","motocross","nascar","race*","track"],"name":"Racetrack (Motorsport)"},"highway/residential":{"icon":"highway-residential","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","cycleway","access"],"geometry":["line"],"tags":{"highway":"residential"},"terms":[],"name":"Residential Road"},"highway/rest_area":{"icon":"car","fields":["name"],"geometry":["point","vertex","area"],"tags":{"highway":"rest_area"},"terms":["rest stop"],"name":"Rest Area"},"highway/road":{"icon":"highway-road","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","access"],"geometry":["line"],"tags":{"highway":"road"},"terms":[],"name":"Unknown Road"},"highway/secondary_link":{"icon":"highway-secondary-link","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"secondary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Secondary Link"},"highway/secondary":{"icon":"highway-secondary","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"secondary"},"terms":[],"name":"Secondary Road"},"highway/service":{"icon":"highway-service","fields":["name","service","oneway","maxspeed","surface","structure","maxheight","access"],"geometry":["line"],"tags":{"highway":"service"},"terms":[],"name":"Service Road"},"highway/service/alley":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"alley"},"reference":{"key":"service","value":"alley"},"name":"Alley"},"highway/service/drive-through":{"icon":"highway-service","fields":["name","oneway","covered","maxheight","maxspeed","structure","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"drive-through"},"reference":{"key":"service","value":"drive-through"},"name":"Drive-Through"},"highway/service/driveway":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"driveway"},"reference":{"key":"service","value":"driveway"},"name":"Driveway"},"highway/service/emergency_access":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"emergency_access"},"reference":{"key":"service","value":"emergency_access"},"name":"Emergency Access"},"highway/service/parking_aisle":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"parking_aisle"},"reference":{"key":"service","value":"parking_aisle"},"name":"Parking Aisle"},"highway/services":{"icon":"car","fields":["name"],"geometry":["point","vertex","area"],"tags":{"highway":"services"},"terms":["services","travel plaza","service station"],"name":"Service Area"},"highway/speed_camera":{"icon":"attraction","geometry":["point"],"fields":["ref"],"tags":{"highway":"speed_camera"},"terms":[],"name":"Speed Camera"},"highway/steps":{"icon":"highway-steps","fields":["surface","lit","width","incline_steps","handrail","step_count"],"geometry":["line"],"tags":{"highway":"steps"},"terms":["stairs","staircase"],"name":"Steps"},"highway/stop":{"icon":"poi-stop","fields":["stop","parallel_direction"],"geometry":["vertex"],"tags":{"highway":"stop"},"terms":["stop","halt","sign"],"name":"Stop Sign"},"highway/street_lamp":{"icon":"poi-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":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"tertiary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Tertiary Link"},"highway/tertiary":{"icon":"highway-tertiary","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"tertiary"},"terms":[],"name":"Tertiary Road"},"highway/track":{"icon":"highway-track","fields":["name","tracktype","surface","width","structure","access","incline","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_mirror":{"geometry":["point","vertex"],"tags":{"highway":"traffic_mirror"},"terms":["blind spot","convex","corner","curved","roadside","round","safety","sphere","visibility"],"name":"Traffic Mirror"},"highway/traffic_signals":{"icon":"poi-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":["name","ref_road_number","oneway","maxspeed","lanes","surface","structure","maxheight","access"],"geometry":["line"],"tags":{"highway":"trunk_link"},"terms":["ramp","on ramp","off ramp"],"name":"Trunk Link"},"highway/trunk":{"icon":"highway-trunk","fields":["name","ref_road_number","oneway","maxspeed","lanes","surface","structure","maxheight","toll","access"],"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":["name","oneway","maxspeed","lanes","surface","structure","maxheight","cycleway","access"],"geometry":["line"],"tags":{"highway":"unclassified"},"terms":[],"name":"Minor/Unclassified Road"},"historic":{"icon":"poi-ruins","fields":["historic","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"*"},"name":"Historic Site"},"historic/archaeological_site":{"icon":"poi-ruins","fields":["name","historic/civilization","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"archaeological_site"},"name":"Archaeological Site"},"historic/boundary_stone":{"icon":"poi-milestone","fields":["name","inscription"],"geometry":["point","vertex"],"tags":{"historic":"boundary_stone"},"name":"Boundary Stone"},"historic/castle":{"icon":"castle","fields":["name","castle_type","building_area","historic/civilization"],"geometry":["point","area"],"tags":{"historic":"castle"},"name":"Castle"},"historic/memorial":{"icon":"monument","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"memorial"},"name":"Memorial"},"historic/monument":{"icon":"monument","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"monument"},"name":"Monument"},"historic/ruins":{"icon":"poi-ruins","fields":["name","historic/civilization","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"ruins"},"name":"Ruins"},"historic/tomb":{"icon":"cemetery","fields":["name","tomb","building_area","inscription"],"geometry":["point","area"],"tags":{"historic":"tomb"},"name":"Tomb"},"historic/wayside_cross":{"icon":"religious-christian","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"wayside_cross"},"name":"Wayside Cross"},"historic/wayside_shrine":{"icon":"landmark","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"wayside_shrine"},"name":"Wayside Shrine"},"junction":{"icon":"poi-junction","fields":["name"],"geometry":["vertex","area"],"tags":{"junction":"yes"},"name":"Junction"},"landuse":{"fields":["name","landuse"],"geometry":["area"],"tags":{"landuse":"*"},"matchScore":0.9,"name":"Land Use"},"landuse/farm":{"icon":"farm","fields":["name","operator","crop"],"geometry":["point","area"],"tags":{"landuse":"farm"},"terms":[],"name":"Farmland","searchable":false},"landuse/allotments":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"allotments"},"terms":["allotment","garden"],"name":"Community Garden"},"landuse/aquaculture":{"icon":"aquarium","fields":["name","operator","produce"],"geometry":["area"],"tags":{"landuse":"aquaculture"},"terms":["fish farm","crustacean","algae","aquafarming","shrimp farm","oyster farm","mariculture","algaculture"],"name":"Aquaculture"},"landuse/basin":{"icon":"water","fields":["name"],"geometry":["area"],"tags":{"landuse":"basin"},"terms":[],"name":"Basin"},"landuse/cemetery":{"icon":"cemetery","fields":["name","religion","denomination"],"geometry":["area"],"tags":{"landuse":"cemetery"},"terms":[],"name":"Cemetery"},"landuse/churchyard":{"fields":["name","religion","denomination"],"geometry":["area"],"tags":{"landuse":"churchyard"},"terms":[],"name":"Churchyard"},"landuse/commercial":{"icon":"commercial","fields":["name"],"geometry":["area"],"tags":{"landuse":"commercial"},"terms":[],"name":"Commercial Area"},"landuse/construction":{"fields":["name","construction","operator"],"geometry":["area"],"tags":{"landuse":"construction"},"terms":[],"name":"Construction"},"landuse/farmland":{"icon":"farm","fields":["name","operator","crop","produce"],"geometry":["area"],"tags":{"landuse":"farmland"},"terms":["crop","grow","plant"],"name":"Farmland"},"landuse/farmyard":{"icon":"farm","fields":["name","operator","crop"],"geometry":["area"],"tags":{"landuse":"farmyard"},"terms":["crop","grow","plant"],"name":"Farmyard"},"landuse/forest":{"icon":"park-alt1","fields":["name","leaf_type","leaf_cycle","produce"],"geometry":["area"],"tags":{"landuse":"forest"},"terms":["tree"],"name":"Forest"},"landuse/garages":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"garages"},"terms":[],"name":"Garages"},"landuse/grass":{"geometry":["area"],"tags":{"landuse":"grass"},"terms":[],"name":"Grass"},"landuse/harbour":{"icon":"harbor","fields":["name","operator"],"geometry":["area"],"terms":["boat"],"tags":{"landuse":"harbour"},"name":"Harbor"},"landuse/industrial":{"icon":"industry","fields":["name"],"geometry":["area"],"tags":{"landuse":"industrial"},"terms":[],"matchScore":0.9,"name":"Industrial Area"},"landuse/landfill":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"landfill"},"terms":["dump"],"name":"Landfill"},"landuse/meadow":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"meadow"},"terms":[],"name":"Meadow"},"landuse/military":{"icon":"poi-military","fields":["name"],"geometry":["area"],"tags":{"landuse":"military"},"terms":[],"matchScore":0.9,"name":"Military Area"},"landuse/military/airfield":{"icon":"airfield","fields":["name","iata","icao"],"geometry":["point","area"],"tags":{"military":"airfield"},"addTags":{"landuse":"military","military":"airfield"},"removeTags":{"landuse":"military","military":"airfield"},"terms":["air force","army","base","bomb","fight","force","guard","heli*","jet","marine","navy","plane","troop","war"],"name":"Military Airfield"},"landuse/military/barracks":{"icon":"poi-military","fields":["name","building_area"],"geometry":["point","area"],"tags":{"military":"barracks"},"addTags":{"landuse":"military","military":"barracks"},"removeTags":{"landuse":"military","military":"barracks"},"terms":["air force","army","base","fight","force","guard","marine","navy","troop","war"],"name":"Barracks"},"landuse/military/bunker":{"icon":"poi-military","fields":["name","bunker_type","building_area"],"geometry":["point","area"],"tags":{"military":"bunker"},"addTags":{"building":"bunker","landuse":"military","military":"bunker"},"removeTags":{"building":"bunker","landuse":"military","military":"bunker"},"terms":["air force","army","base","fight","force","guard","marine","navy","troop","war"],"name":"Military Bunker"},"landuse/military/checkpoint":{"icon":"barrier","fields":["name"],"geometry":["point","vertex","area"],"tags":{"military":"checkpoint"},"addTags":{"landuse":"military","military":"checkpoint"},"removeTags":{"landuse":"military","military":"checkpoint"},"terms":["air force","army","base","force","guard","marine","navy","troop","war"],"name":"Checkpoint"},"landuse/military/danger_area":{"icon":"danger","fields":["name"],"geometry":["point","vertex","area"],"tags":{"military":"danger_area"},"addTags":{"landuse":"military","military":"danger_area"},"removeTags":{"landuse":"military","military":"danger_area"},"terms":["air force","army","base","blast","bomb","explo*","force","guard","mine","marine","navy","troop","war"],"name":"Danger Area"},"landuse/military/naval_base":{"icon":"poi-military","fields":["name"],"geometry":["point","area"],"tags":{"military":"naval_base"},"addTags":{"landuse":"military","military":"naval_base"},"removeTags":{"landuse":"military","military":"naval_base"},"terms":["base","fight","force","guard","marine","navy","ship","sub","troop","war"],"name":"Naval Base"},"landuse/military/nuclear_explosion_site":{"icon":"danger","fields":["name"],"geometry":["point","vertex","area"],"tags":{"military":"nuclear_explosion_site"},"addTags":{"landuse":"military","military":"nuclear_explosion_site"},"removeTags":{"landuse":"military","military":"nuclear_explosion_site"},"terms":["atom","blast","bomb","detonat*","nuke","site","test"],"name":"Nuclear Explosion Site"},"landuse/military/obstacle_course":{"icon":"poi-military","geometry":["point","area"],"tags":{"military":"obstacle_course"},"addTags":{"landuse":"military","military":"obstacle_course"},"removeTags":{"landuse":"military","military":"obstacle_course"},"terms":["army","base","force","guard","marine","navy","troop","war"],"name":"Obstacle Course"},"landuse/military/office":{"icon":"poi-military","fields":["name","building_area"],"geometry":["point","area"],"tags":{"military":"office"},"addTags":{"landuse":"military","military":"office"},"removeTags":{"landuse":"military","military":"office"},"terms":["air force","army","base","enlist","fight","force","guard","marine","navy","recruit","troop","war"],"name":"Military Office"},"landuse/military/range":{"icon":"poi-military","fields":["name"],"geometry":["point","area"],"tags":{"military":"range"},"addTags":{"landuse":"military","military":"range"},"removeTags":{"landuse":"military","military":"range"},"terms":["air force","army","base","fight","fire","force","guard","gun","marine","navy","rifle","shoot*","snip*","train","troop","war"],"name":"Military Range"},"landuse/military/training_area":{"icon":"poi-military","fields":["name"],"geometry":["point","area"],"tags":{"military":"training_area"},"addTags":{"landuse":"military","military":"training_area"},"removeTags":{"landuse":"military","military":"training_area"},"terms":["air force","army","base","fight","fire","force","guard","gun","marine","navy","rifle","shoot*","snip*","train","troop","war"],"name":"Training Area"},"landuse/orchard":{"icon":"park-alt1","fields":["name","operator","trees"],"geometry":["area"],"tags":{"landuse":"orchard"},"terms":["fruit"],"name":"Orchard"},"landuse/plant_nursery":{"icon":"garden","fields":["name","operator","plant"],"geometry":["area"],"tags":{"landuse":"plant_nursery"},"terms":["flower","garden","grow","vivero"],"name":"Plant Nursery"},"landuse/quarry":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"quarry"},"terms":[],"name":"Quarry"},"landuse/railway":{"icon":"rail","fields":["operator"],"geometry":["area"],"tags":{"landuse":"railway"},"terms":["rail","train","track"],"name":"Railway Corridor"},"landuse/recreation_ground":{"icon":"pitch","geometry":["area"],"fields":["name"],"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"],"fields":["name"],"tags":{"landuse":"retail"},"name":"Retail Area"},"landuse/vineyard":{"fields":["name","operator","grape_variety"],"geometry":["area"],"tags":{"landuse":"vineyard"},"addTags":{"landuse":"vineyard","crop":"grape"},"removeTags":{"landuse":"vineyard","crop":"grape","grape_variety":"*"},"terms":["grape","wine"],"name":"Vineyard"},"leisure":{"icon":"pitch","fields":["name","leisure"],"geometry":["point","vertex","area"],"tags":{"leisure":"*"},"name":"Leisure"},"leisure/adult_gaming_centre":{"icon":"poi-dice","fields":["name","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":{"icon":"poi-binoculars","fields":["building_area"],"geometry":["point","area"],"tags":{"leisure":"bird_hide"},"terms":["machan","ornithology"],"name":"Bird Hide"},"leisure/bowling_alley":{"icon":"poi-bowling","fields":["name","operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":[],"tags":{"leisure":"bowling_alley"},"name":"Bowling Alley"},"leisure/common":{"icon":"poi-foot","geometry":["point","area"],"fields":["name"],"terms":["open space"],"tags":{"leisure":"common"},"name":"Common"},"leisure/dance":{"icon":"music","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ballroom","jive","swing","tango","waltz"],"tags":{"leisure":"dance"},"name":"Dance Hall"},"leisure/dog_park":{"icon":"dog-park","geometry":["point","area"],"fields":["name"],"terms":[],"tags":{"leisure":"dog_park"},"name":"Dog Park"},"leisure/firepit":{"icon":"fire-station","geometry":["point","area"],"tags":{"leisure":"firepit"},"terms":["fireplace","campfire"],"name":"Firepit"},"leisure/fitness_centre":{"icon":"pitch","fields":["name","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":["name","sport","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["studio"],"tags":{"leisure":"fitness_centre","sport":"yoga"},"reference":{"key":"sport","value":"yoga"},"name":"Yoga Studio"},"leisure/fitness_station":{"icon":"pitch","fields":["name","sport","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station"},"terms":["fitness","gym"],"name":"Outdoor Fitness Station"},"leisure/garden":{"icon":"garden","fields":["name","access_simple"],"geometry":["point","vertex","area"],"tags":{"leisure":"garden"},"name":"Garden"},"leisure/golf_course":{"icon":"golf","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["links"],"tags":{"leisure":"golf_course"},"name":"Golf Course"},"leisure/horse_riding":{"icon":"horse-riding","fields":["name","access_simple","operator","address","building"],"geometry":["point","area"],"terms":["equestrian","stable"],"tags":{"leisure":"horse_riding"},"name":"Horseback Riding Facility"},"leisure/ice_rink":{"icon":"pitch","fields":["name","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":["name","operator","address","capacity","fee","sanitary_dump_station","power_supply","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"terms":["boat"],"tags":{"leisure":"marina"},"name":"Marina"},"leisure/miniature_golf":{"icon":"golf","fields":["name","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"],"fields":["name"],"tags":{"leisure":"nature_reserve"},"terms":["protected","wildlife"],"name":"Nature Reserve"},"leisure/park":{"icon":"park","geometry":["point","area"],"fields":["name"],"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":{"icon":"picnic-site","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"},"reference":{"key":"sport","value":"american_football"},"terms":[],"name":"American Football Field"},"leisure/pitch/baseball":{"icon":"baseball","fields":["lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"baseball"},"reference":{"key":"sport","value":"baseball"},"terms":[],"name":"Baseball Diamond"},"leisure/pitch/basketball":{"icon":"basketball","fields":["surface","hoops","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"basketball"},"reference":{"key":"sport","value":"basketball"},"terms":[],"name":"Basketball Court"},"leisure/pitch/beachvolleyball":{"icon":"basketball","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"beachvolleyball"},"addTags":{"leisure":"pitch","sport":"beachvolleyball","surface":"sand"},"removeTags":{"leisure":"pitch","sport":"beachvolleyball","surface":"sand"},"reference":{"key":"sport","value":"beachvolleyball"},"terms":["volleyball"],"name":"Beach Volleyball Court"},"leisure/pitch/bowls":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"bowls"},"reference":{"key":"sport","value":"bowls"},"terms":[],"name":"Bowling Green"},"leisure/pitch/cricket":{"icon":"cricket","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"cricket"},"reference":{"key":"sport","value":"cricket"},"terms":[],"name":"Cricket Field"},"leisure/pitch/equestrian":{"icon":"horse-riding","fields":["surface","lit","building"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"equestrian"},"reference":{"key":"sport","value":"equestrian"},"terms":["dressage","equestrian","horse","horseback","riding"],"name":"Riding Arena"},"leisure/pitch/rugby_league":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"rugby_league"},"reference":{"key":"sport","value":"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"},"reference":{"key":"sport","value":"rugby_union"},"terms":[],"name":"Rugby Union Field"},"leisure/pitch/skateboard":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"skateboard"},"reference":{"key":"sport","value":"skateboard"},"terms":[],"name":"Skate Park"},"leisure/pitch/soccer":{"icon":"soccer","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"soccer"},"reference":{"key":"sport","value":"soccer"},"terms":["football"],"name":"Soccer Field"},"leisure/pitch/table_tennis":{"icon":"tennis","fields":["lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"table_tennis"},"reference":{"key":"sport","value":"table_tennis"},"terms":["table tennis","ping pong"],"name":"Ping Pong Table"},"leisure/pitch/tennis":{"icon":"tennis","fields":["surface","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"tennis"},"reference":{"key":"sport","value":"tennis"},"terms":[],"name":"Tennis Court"},"leisure/pitch/volleyball":{"icon":"basketball","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"volleyball"},"reference":{"key":"sport","value":"volleyball"},"terms":[],"name":"Volleyball Court"},"leisure/playground":{"icon":"playground","geometry":["point","area"],"terms":["jungle gym","play area"],"tags":{"leisure":"playground"},"name":"Playground"},"leisure/resort":{"icon":"lodging","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"resort"},"name":"Resort"},"leisure/running_track":{"icon":"pitch","fields":["surface","sport_racing_nonmotor","lit","width","lanes"],"geometry":["point","line","area"],"tags":{"leisure":"track","sport":"running"},"terms":["race*","running","sprint","track"],"name":"Racetrack (Running)"},"leisure/slipway":{"icon":"poi-beach","geometry":["point","line"],"terms":["boat launch","boat ramp"],"tags":{"leisure":"slipway"},"name":"Slipway"},"leisure/sports_centre":{"icon":"pitch","fields":["name","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":["name","access_simple","operator","address","building"],"geometry":["point","area"],"terms":["dive","water"],"tags":{"leisure":"sports_centre","sport":"swimming"},"reference":{"key":"sport","value":"swimming"},"name":"Swimming Pool Facility"},"leisure/stadium":{"icon":"pitch","fields":["name","sport","address"],"geometry":["point","area"],"tags":{"leisure":"stadium"},"name":"Stadium"},"leisure/swimming_pool":{"icon":"swimming","fields":["name","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_nonmotor","lit","width","lanes"],"geometry":["point","line","area"],"tags":{"leisure":"track"},"terms":["cycle","dog","greyhound","horse","race*","track"],"name":"Racetrack (Non-Motorsport)"},"leisure/water_park":{"icon":"swimming","fields":["name","operator","address"],"geometry":["point","area"],"terms":["swim","pool","dive"],"tags":{"leisure":"water_park"},"name":"Water Park"},"line":{"name":"Line","fields":["name"],"tags":{},"geometry":["line"],"matchScore":0.1},"man_made":{"icon":"poi-storage-tank","fields":["name","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":{"icon":"triangle","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":{"icon":"poi-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":{"icon":"embassy","geometry":["point"],"tags":{"man_made":"flagpole"},"name":"Flagpole"},"man_made/gasometer":{"icon":"poi-storage-tank","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":{"icon":"poi-mast","fields":["tower/type","tower/construction","height","communication_multi"],"geometry":["point"],"terms":["antenna","broadcast tower","cell phone tower","cell tower","communication mast","communication tower","guyed tower","mobile phone tower","radio mast","radio tower","television tower","transmission mast","transmission tower","tv tower"],"tags":{"man_made":"mast"},"name":"Mast"},"man_made/observation":{"icon":"poi-tower","geometry":["point","area"],"terms":["lookout tower","fire tower"],"tags":{"man_made":"tower","tower:type":"observation"},"name":"Observation Tower"},"man_made/petroleum_well":{"icon":"poi-storage-tank","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","jetty"],"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":{"icon":"water","geometry":["point","area"],"tags":{"man_made":"pumping_station"},"name":"Pumping Station"},"man_made/silo":{"icon":"poi-silo","fields":["building_area","crop"],"geometry":["point","area"],"terms":["grain","corn","wheat"],"tags":{"man_made":"silo"},"name":"Silo"},"man_made/storage_tank":{"icon":"poi-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_camera":{"icon":"attraction","geometry":["point"],"fields":["surveillance","surveillance/type","camera/type","camera/mount","camera/direction","surveillance/zone","contact/webcam"],"terms":["anpr","alpr","camera","car plate recognition","cctv","guard","license plate recognition","monitoring","number plate recognition","security","video","webcam"],"tags":{"man_made":"surveillance","surveillance:type":"camera"},"name":"Surveillance Camera"},"man_made/surveillance":{"icon":"attraction","geometry":["point"],"fields":["surveillance","surveillance/type","surveillance/zone"],"terms":["anpr","alpr","camera","car plate recognition","cctv","guard","license plate recognition","monitoring","number plate recognition","security","video","webcam"],"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":{"icon":"poi-tower","fields":["tower/type","tower/construction","height"],"geometry":["point","area"],"tags":{"man_made":"tower"},"name":"Tower"},"man_made/wastewater_plant":{"icon":"water","fields":["name","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":{"icon":"water","fields":["operator"],"geometry":["point","area"],"tags":{"man_made":"water_well"},"name":"Water Well"},"man_made/water_works":{"icon":"water","fields":["name","operator","address"],"geometry":["point","area"],"tags":{"man_made":"water_works"},"name":"Water Works"},"man_made/watermill":{"icon":"buddhism","fields":["building_area"],"geometry":["point","area"],"terms":["water","wheel","mill"],"tags":{"man_made":"watermill"},"name":"Watermill"},"man_made/windmill":{"icon":"poi-windmill","fields":["building_area"],"geometry":["point","area"],"terms":["wind","wheel","mill"],"tags":{"man_made":"windmill"},"name":"Windmill"},"man_made/works":{"icon":"industry","fields":["name","operator","address","building_area","product"],"geometry":["point","area"],"terms":["assembly","build","brewery","car","plant","plastic","processing","manufacture","refinery"],"tags":{"man_made":"works"},"name":"Factory"},"manhole":{"icon":"circle-stroked","fields":["manhole","operator","label","ref"],"geometry":["point","vertex"],"tags":{"manhole":"*"},"terms":["cover","hole","sewer","sewage","telecom"],"name":"Manhole"},"manhole/drain":{"icon":"water","fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"manhole":"drain"},"terms":["cover","drain","hole","rain","sewer","sewage","storm"],"name":"Storm Drain"},"manhole/telecom":{"icon":"circle-stroked","fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"manhole":"telecom"},"terms":["cover","phone","hole","telecom","telephone","bt"],"name":"Telecom Manhole"},"natural":{"icon":"natural","fields":["name","natural"],"geometry":["point","vertex","area"],"tags":{"natural":"*"},"name":"Natural"},"natural/bare_rock":{"geometry":["area"],"tags":{"natural":"bare_rock"},"terms":["rock"],"name":"Bare Rock"},"natural/bay":{"icon":"poi-beach","geometry":["point","area"],"fields":["name"],"tags":{"natural":"bay"},"terms":[],"name":"Bay"},"natural/beach":{"icon":"poi-beach","fields":["surface"],"geometry":["point","area"],"tags":{"natural":"beach"},"terms":["shore"],"name":"Beach"},"natural/cave_entrance":{"icon":"triangle","geometry":["point","area"],"fields":["fee","access_simple"],"tags":{"natural":"cave_entrance"},"terms":["cavern","hollow","grotto","shelter","cavity"],"name":"Cave Entrance"},"natural/cliff":{"icon":"triangle","geometry":["point","vertex","line","area"],"tags":{"natural":"cliff"},"terms":["escarpment"],"name":"Cliff"},"natural/coastline":{"geometry":["line"],"tags":{"natural":"coastline"},"terms":["shore"],"name":"Coastline"},"natural/fell":{"geometry":["area"],"tags":{"natural":"fell"},"terms":[],"name":"Fell"},"natural/glacier":{"geometry":["area"],"tags":{"natural":"glacier"},"terms":[],"name":"Glacier"},"natural/grassland":{"geometry":["area"],"tags":{"natural":"grassland"},"terms":["prairie","savanna"],"name":"Grassland"},"natural/heath":{"geometry":["area"],"tags":{"natural":"heath"},"terms":[],"name":"Heath"},"natural/peak":{"icon":"mountain","fields":["name","elevation"],"geometry":["point","vertex"],"tags":{"natural":"peak"},"terms":["acme","aiguille","alp","climax","crest","crown","hill","mount","mountain","pinnacle","summit","tip","top"],"name":"Peak"},"natural/ridge":{"geometry":["line"],"tags":{"natural":"ridge"},"terms":["crest"],"name":"Ridge"},"natural/saddle":{"icon":"triangle-stroked","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"saddle"},"terms":["pass","mountain pass","top"],"name":"Saddle"},"natural/sand":{"geometry":["area"],"tags":{"natural":"sand"},"terms":["desert"],"name":"Sand"},"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":{"icon":"water","geometry":["point","vertex"],"tags":{"natural":"spring"},"terms":[],"name":"Spring"},"natural/tree_row":{"icon":"park","fields":["leaf_type","leaf_cycle","denotation"],"geometry":["line"],"tags":{"natural":"tree_row"},"terms":[],"name":"Tree row"},"natural/tree":{"icon":"park","fields":["leaf_type_singular","leaf_cycle_singular","denotation"],"geometry":["point","vertex"],"tags":{"natural":"tree"},"terms":[],"name":"Tree"},"natural/volcano":{"icon":"volcano","fields":["name","elevation"],"geometry":["point","vertex"],"tags":{"natural":"volcano"},"terms":["mountain","crater"],"name":"Volcano"},"natural/water":{"icon":"water","fields":["water"],"geometry":["area"],"tags":{"natural":"water"},"name":"Water"},"natural/water/lake":{"icon":"water","geometry":["area"],"fields":["name"],"tags":{"natural":"water","water":"lake"},"reference":{"key":"natural","value":"water"},"terms":["lakelet","loch","mere"],"name":"Lake"},"natural/water/pond":{"icon":"water","geometry":["area"],"fields":["name"],"tags":{"natural":"water","water":"pond"},"reference":{"key":"natural","value":"water"},"terms":["lakelet","millpond","tarn","pool","mere"],"name":"Pond"},"natural/water/reservoir":{"icon":"water","geometry":["area"],"fields":["name"],"tags":{"natural":"water","water":"reservoir"},"reference":{"key":"natural","value":"water"},"name":"Reservoir"},"natural/wetland":{"icon":"wetland","fields":["wetland"],"geometry":["point","area"],"tags":{"natural":"wetland"},"terms":["bog","marsh","reedbed","swamp","tidalflat"],"name":"Wetland"},"natural/wood":{"icon":"park-alt1","fields":["leaf_type","leaf_cycle"],"geometry":["point","area"],"tags":{"natural":"wood"},"terms":["tree"],"name":"Wood"},"noexit/yes":{"icon":"barrier","geometry":["vertex"],"terms":["no exit","road end","dead end"],"tags":{"noexit":"yes"},"reference":{"key":"noexit","value":"*"},"name":"No Exit"},"office":{"icon":"commercial","fields":["name","office","address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"*"},"terms":[],"name":"Office"},"office/physician":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"physician"},"searchable":false,"name":"Physician"},"office/travel_agent":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"travel_agent"},"reference":{"key":"shop","value":"travel_agency"},"terms":[],"name":"Travel Agency","searchable":false},"office/accountant":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"accountant"},"terms":[],"name":"Accountant"},"office/administrative":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"administrative"},"terms":[],"name":"Administrative Office"},"office/architect":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"architect"},"terms":[],"name":"Architect"},"office/company":{"icon":"commercial","fields":["name","address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"company"},"terms":[],"name":"Company Office"},"office/coworking":{"icon":"commercial","fields":["name","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["coworking","office"],"tags":{"office":"coworking"},"reference":{"key":"amenity","value":"coworking_space"},"name":"Coworking Space"},"office/educational_institution":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"educational_institution"},"terms":[],"name":"Educational Institution"},"office/employment_agency":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"employment_agency"},"terms":["job"],"name":"Employment Agency"},"office/estate_agent":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"estate_agent"},"terms":[],"name":"Real Estate Office"},"office/financial":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"financial"},"terms":[],"name":"Financial Office"},"office/government":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"government"},"terms":[],"name":"Government Office"},"office/government/register_office":{"icon":"town-hall","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":["clerk","marriage","death","birth","certificate"],"tags":{"office":"government","government":"register_office"},"reference":{"key":"government","value":"register_office"},"name":"Register Office"},"office/insurance":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"insurance"},"terms":[],"name":"Insurance Office"},"office/it":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"it"},"terms":[],"name":"IT Office"},"office/lawyer":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"lawyer"},"terms":[],"name":"Law Office"},"office/lawyer/notary":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"lawyer","lawyer":"notary"},"reference":{"key":"office","value":"notary"},"terms":["clerk","signature","wills","deeds","estate"],"name":"Notary Office"},"office/newspaper":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"newspaper"},"terms":[],"name":"Newspaper"},"office/ngo":{"icon":"commercial","fields":["name","address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"ngo"},"terms":[],"name":"NGO Office"},"office/political_party":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"political_party"},"terms":[],"name":"Political Party"},"office/research":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"research"},"terms":[],"name":"Research Office"},"office/telecommunication":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"telecommunication"},"terms":[],"name":"Telecom Office"},"office/therapist":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"therapist"},"terms":[],"name":"Therapist"},"piste":{"icon":"skiing","fields":["name","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/farm":{"icon":"farm","geometry":["point","area"],"fields":["name"],"tags":{"place":"farm"},"name":"Farm","searchable":false},"place/city":{"icon":"city","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"city"},"name":"City"},"place/hamlet":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"hamlet"},"name":"Hamlet"},"place/island":{"icon":"mountain","geometry":["point","area"],"fields":["name"],"terms":["archipelago","atoll","bar","cay","isle","islet","key","reef"],"tags":{"place":"island"},"name":"Island"},"place/isolated_dwelling":{"icon":"home","geometry":["point","area"],"fields":["name"],"tags":{"place":"isolated_dwelling"},"name":"Isolated Dwelling"},"place/locality":{"icon":"triangle-stroked","geometry":["point","area"],"fields":["name"],"tags":{"place":"locality"},"name":"Locality"},"place/neighbourhood":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"neighbourhood"},"terms":["neighbourhood"],"name":"Neighborhood"},"place/quarter":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"quarter"},"terms":["boro","borough","quarter"],"name":"Sub-Borough / Quarter"},"place/square":{"icon":"poi-foot","geometry":["point","area"],"fields":["name"],"tags":{"place":"square"},"name":"Square"},"place/suburb":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"suburb"},"terms":["boro","borough","quarter"],"name":"Borough / Suburb"},"place/town":{"icon":"town","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"town"},"name":"Town"},"place/village":{"icon":"village","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"village"},"name":"Village"},"point":{"name":"Point","fields":["name"],"tags":{},"geometry":["point"],"matchScore":0.1},"power/sub_station":{"fields":["substation","operator","building"],"geometry":["point","area"],"tags":{"power":"sub_station"},"reference":{"key":"power","value":"substation"},"name":"Substation","searchable":false},"power/generator":{"icon":"poi-power","fields":["operator","generator/source","generator/method","generator/type","generator/output/electricity"],"geometry":["point","vertex","area"],"terms":["hydro","solar","turbine","wind"],"tags":{"power":"generator"},"name":"Power Generator"},"power/generator/source_nuclear":{"icon":"poi-nuclear","fields":["operator","generator/source","generator/method","generator/type","generator/output/electricity"],"geometry":["point","vertex","area"],"terms":["fission","generator","nuclear","nuke","reactor"],"tags":{"power":"generator","generator:source":"nuclear","generator:method":"fission"},"reference":{"key":"generator:source","value":"nuclear"},"name":"Nuclear Reactor"},"power/generator/source_wind":{"icon":"poi-wind","fields":["operator","generator/source","generator/method","generator/type","generator/output/electricity","height"],"geometry":["point","vertex","area"],"terms":["generator","turbine","windmill","wind"],"tags":{"power":"generator","generator:source":"wind","generator:method":"wind_turbine"},"reference":{"key":"generator:source","value":"wind"},"name":"Wind Turbine"},"power/line":{"icon":"power-line","geometry":["line"],"tags":{"power":"line"},"name":"Power Line"},"power/minor_line":{"icon":"power-line","geometry":["line"],"tags":{"power":"minor_line"},"name":"Minor Power Line"},"power/plant":{"icon":"industry","fields":["name","operator","address","plant/output/electricity","start_date"],"geometry":["area"],"tags":{"power":"plant"},"addTags":{"power":"plant","landuse":"industrial"},"removeTags":{"power":"plant","landuse":"industrial"},"terms":["coal","gas","generat*","hydro","nuclear","power","station"],"name":"Power Station Grounds"},"power/pole":{"geometry":["vertex"],"tags":{"power":"pole"},"name":"Power Pole"},"power/substation":{"icon":"poi-power","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":{"icon":"poi-power","geometry":["point","vertex","area"],"tags":{"power":"transformer"},"name":"Transformer"},"public_transport/platform":{"icon":"bus","fields":["name","ref_platform","network","operator","shelter"],"geometry":["point","vertex","line","area"],"tags":{"public_transport":"platform"},"name":"Platform"},"public_transport/stop_position":{"icon":"bus","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position"},"name":"Stop Position"},"railway/abandoned":{"icon":"railway-abandoned","geometry":["line"],"tags":{"railway":"abandoned"},"fields":["name","structure","service_rail"],"terms":[],"name":"Abandoned Railway"},"railway/buffer_stop":{"icon":"poi-buffer-stop","geometry":["vertex"],"tags":{"railway":"buffer_stop"},"terms":["stop","halt","buffer"],"name":"Buffer Stop"},"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/derail":{"icon":"roadblock","geometry":["vertex"],"tags":{"railway":"derail"},"terms":["derailer"],"name":"Railway Derailer"},"railway/disused":{"icon":"railway-disused","geometry":["line"],"tags":{"railway":"disused"},"fields":["structure","service_rail"],"terms":[],"name":"Disused Railway"},"railway/funicular":{"icon":"railway-rail","geometry":["line"],"terms":["venicular","cliff railway","cable car","cable railway","funicular railway"],"fields":["structure","gauge","service_rail"],"tags":{"railway":"funicular"},"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/milestone":{"icon":"poi-milestone","geometry":["point","vertex"],"fields":["milestone_position"],"tags":{"railway":"milestone"},"terms":["milestone","marker"],"name":"Railway Milestone"},"railway/monorail":{"icon":"railway-monorail","geometry":["line"],"tags":{"railway":"monorail"},"fields":["name","structure","electrified","service_rail"],"terms":[],"name":"Monorail"},"railway/narrow_gauge":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"narrow_gauge"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["narrow gauge railway","narrow gauge railroad"],"name":"Narrow Gauge Rail"},"railway/platform":{"icon":"highway-footway","fields":["name","ref_platform","surface","lit","shelter"],"geometry":["line","area"],"tags":{"railway":"platform"},"name":"Railway Platform"},"railway/rail":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"rail"},"fields":["name","structure","gauge","electrified","maxspeed","service_rail"],"terms":[],"name":"Rail"},"railway/signal":{"icon":"poi-railway-signals","geometry":["point","vertex"],"tags":{"railway":"signal"},"terms":["signal","lights"],"name":"Railway Signal"},"railway/station":{"icon":"rail","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"tags":{"railway":"station"},"terms":["train station","station"],"name":"Railway Station"},"railway/subway_entrance":{"icon":"entrance","geometry":["point","vertex"],"fields":["name"],"tags":{"railway":"subway_entrance"},"terms":["metro","transit"],"name":"Subway Entrance"},"railway/subway":{"icon":"railway-subway","geometry":["line"],"tags":{"railway":"subway"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["metro","transit"],"name":"Subway"},"railway/switch":{"icon":"poi-junction","geometry":["vertex"],"tags":{"railway":"switch"},"terms":["switch","points"],"name":"Railway Switch"},"railway/train_wash":{"icon":"rail","geometry":["point","vertex","area"],"fields":["operator","building_area"],"tags":{"railway":"wash"},"terms":["wash","clean"],"name":"Train Wash"},"railway/tram_stop":{"icon":"rail-light","fields":["name","network","operator"],"geometry":["vertex"],"tags":{"railway":"tram_stop"},"terms":["light rail","streetcar","tram","trolley"],"name":"Tram Stop"},"railway/tram":{"icon":"railway-light-rail","geometry":["line"],"tags":{"railway":"tram"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["light rail","streetcar","tram","trolley"],"name":"Tram"},"relation":{"name":"Relation","icon":"relation","tags":{},"geometry":["relation"],"fields":["name","relation"]},"route/ferry":{"icon":"ferry-line","geometry":["line"],"fields":["name"],"tags":{"route":"ferry"},"name":"Ferry Route"},"shop":{"icon":"shop","fields":["name","shop","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"*"},"terms":[],"name":"Shop"},"shop/fishmonger":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"fishmonger"},"reference":{"key":"shop","value":"seafood"},"name":"Fishmonger","searchable":false},"shop/vacant":{"icon":"shop","fields":["name","address","building_area"],"geometry":["point","area"],"tags":{"shop":"vacant"},"name":"Vacant Shop","searchable":false},"shop/alcohol":{"icon":"alcohol-shop","fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"antiques"},"name":"Antiques Shop"},"shop/appliance":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["air conditioner","appliance","dishwasher","dryer","freezer","fridge","grill","kitchen","oven","refrigerator","stove","washer","washing machine"],"tags":{"shop":"appliance"},"name":"Appliance Store"},"shop/art":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"baby_goods"},"name":"Baby Goods Store"},"shop/bag":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["handbag","purse"],"tags":{"shop":"bag"},"name":"Bag/Luggage Store"},"shop/bakery":{"icon":"bakery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bakery"},"name":"Bakery"},"shop/bathroom_furnishing":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bathroom_furnishing"},"name":"Bathroom Furnishing Store"},"shop/beauty":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["manicure","pedicure"],"tags":{"shop":"beauty","beauty":"nails"},"reference":{"key":"shop","value":"beauty"},"name":"Nail Salon"},"shop/beauty/tanning":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"beauty","beauty":"tanning"},"reference":{"key":"leisure","value":"tanning_salon"},"name":"Tanning Salon"},"shop/bed":{"icon":"lodging","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bed"},"name":"Bedding/Mattress Store"},"shop/beverages":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"beverages"},"name":"Beverage Store"},"shop/bicycle":{"icon":"bicycle","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["betting"],"tags":{"shop":"bookmaker"},"name":"Bookmaker"},"shop/books":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"shop":"books"},"name":"Book Store"},"shop/boutique":{"icon":"shop","fields":["name","clothes","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"boutique"},"name":"Boutique"},"shop/butcher":{"icon":"slaughterhouse","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["meat"],"tags":{"shop":"butcher"},"name":"Butcher"},"shop/candles":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"candles"},"name":"Candle Shop"},"shop/car_parts":{"icon":"car","fields":["name","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":["name","operator","address","building_area","opening_hours","service/vehicle"],"geometry":["point","area"],"terms":["auto","garage","service"],"tags":{"shop":"car_repair"},"name":"Car Repair Shop"},"shop/car":{"icon":"car","fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car"},"name":"Car Dealership"},"shop/carpet":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["rug"],"tags":{"shop":"carpet"},"name":"Carpet Store"},"shop/charity":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"cheese"},"name":"Cheese Store"},"shop/chemist":{"icon":"grocery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"chemist"},"terms":["med*","drug*","gift"],"name":"Drugstore"},"shop/chocolate":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"chocolate"},"name":"Chocolate Store"},"shop/clothes":{"icon":"clothing-store","fields":["name","clothes","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"clothes"},"name":"Clothing Store"},"shop/coffee":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"coffee"},"name":"Coffee Store"},"shop/computer":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"computer"},"name":"Computer Store"},"shop/confectionery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"confectionery"},"name":"Candy Store"},"shop/convenience":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"convenience"},"name":"Convenience Store"},"shop/copyshop":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"copyshop"},"name":"Copy Store"},"shop/cosmetics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"cosmetics"},"name":"Cosmetics Store"},"shop/craft":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["drape*","window"],"tags":{"shop":"curtain"},"name":"Curtain Store"},"shop/dairy":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["milk","egg","cheese"],"tags":{"shop":"dairy"},"name":"Dairy Store"},"shop/deli":{"icon":"restaurant","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lunch","meat","sandwich"],"tags":{"shop":"deli"},"name":"Deli"},"shop/department_store":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"department_store"},"name":"Department Store"},"shop/doityourself":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"doityourself"},"name":"DIY Store"},"shop/dry_cleaning":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"dry_cleaning"},"name":"Dry Cleaner"},"shop/e-cigarette":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["appliance","audio","blueray","camera","computer","dvd","home theater","radio","speaker","tv","video"],"tags":{"shop":"electronics"},"name":"Electronics Store"},"shop/erotic":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sex","porn"],"tags":{"shop":"erotic"},"name":"Erotic Store"},"shop/fabric":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sew"],"tags":{"shop":"fabric"},"name":"Fabric Store"},"shop/farm":{"icon":"shop","fields":["name","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":["name","clothes","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"fashion"},"name":"Fashion Store"},"shop/florist":{"icon":"florist","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["flower"],"tags":{"shop":"florist"},"name":"Florist"},"shop/frame":{"icon":"shop","fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["oven","stove"],"tags":{"shop":"furnace"},"name":"Furnace Store"},"shop/furniture":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["chair","sofa","table"],"tags":{"shop":"furniture"},"name":"Furniture Store"},"shop/garden_centre":{"icon":"garden-center","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscape","mulch","shrub","tree"],"tags":{"shop":"garden_centre"},"name":"Garden Center"},"shop/gas":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cng","lpg","natural gas","propane","refill","tank"],"tags":{"shop":"gas"},"name":"Bottled Gas Shop"},"shop/gift":{"icon":"gift","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["souvenir"],"tags":{"shop":"gift"},"name":"Gift Shop"},"shop/greengrocer":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fruit","vegetable"],"tags":{"shop":"greengrocer"},"name":"Greengrocer"},"shop/hairdresser":{"icon":"hairdresser","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["barber"],"tags":{"shop":"hairdresser"},"name":"Hairdresser"},"shop/hardware":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"hardware"},"name":"Hardware Store"},"shop/hearing_aids":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"hearing_aids"},"name":"Hearing Aids Store"},"shop/herbalist":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"herbalist"},"name":"Herbalist"},"shop/hifi":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["stereo","video"],"tags":{"shop":"hifi"},"name":"Hifi Store"},"shop/houseware":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["home","household"],"tags":{"shop":"houseware"},"name":"Houseware Store"},"shop/interior_decoration":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"interior_decoration"},"name":"Interior Decoration Store"},"shop/jewelry":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["diamond","gem","ring"],"tags":{"shop":"jewelry"},"name":"Jeweler"},"shop/kiosk":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"kiosk"},"name":"News Kiosk"},"shop/kitchen":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"kitchen"},"name":"Kitchen Design Store"},"shop/laundry":{"icon":"laundry","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"laundry"},"name":"Laundry"},"shop/leather":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"leather"},"name":"Leather Store"},"shop/locksmith":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["key","lockpick"],"tags":{"shop":"locksmith"},"name":"Locksmith"},"shop/lottery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"lottery"},"name":"Lottery Shop"},"shop/mall":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["shopping"],"tags":{"shop":"mall"},"name":"Mall"},"shop/massage":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"massage"},"name":"Massage Shop"},"shop/medical_supply":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"medical_supply"},"name":"Medical Supply Store"},"shop/mobile_phone":{"icon":"mobile-phone","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"mobile_phone"},"name":"Mobile Phone Store"},"shop/money_lender":{"icon":"bank","fields":["name","operator","address","building_area","opening_hours","currency_multi"],"geometry":["point","area"],"tags":{"shop":"money_lender"},"name":"Money Lender"},"shop/motorcycle":{"icon":"scooter","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["bike"],"tags":{"shop":"motorcycle"},"name":"Motorcycle Dealership"},"shop/music":{"icon":"music","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["CD","vinyl"],"tags":{"shop":"music"},"name":"Music Store"},"shop/musical_instrument":{"icon":"music","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["guitar"],"tags":{"shop":"musical_instrument"},"name":"Musical Instrument Store"},"shop/newsagent":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"newsagent"},"name":"Newspaper/Magazine Shop"},"shop/nutrition_supplements":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"nutrition_supplements"},"name":"Nutrition Supplements Store"},"shop/optician":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["eye","glasses"],"tags":{"shop":"optician"},"name":"Optician"},"shop/organic":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"supermarket","organic":"only"},"name":"Organic Goods Store"},"shop/outdoor":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["camping","climbing","hiking"],"tags":{"shop":"outdoor"},"name":"Outdoors Store"},"shop/paint":{"icon":"water","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"paint"},"name":"Paint Store"},"shop/pastry":{"icon":"bakery","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pawnbroker"},"name":"Pawn Shop"},"shop/perfumery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"perfumery"},"name":"Perfume Store"},"shop/pet":{"icon":"dog-park","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["animal","cat","dog","fish","kitten","puppy","reptile"],"tags":{"shop":"pet"},"name":"Pet Store"},"shop/photo":{"icon":"attraction","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["camera","film"],"tags":{"shop":"photo"},"name":"Photography Store"},"shop/pyrotechnics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pyrotechnics"},"name":"Fireworks Store"},"shop/radiotechnics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"radiotechnics"},"name":"Radio/Electronic Component Store"},"shop/religion":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","religion","denomination"],"geometry":["point","area"],"tags":{"shop":"religion"},"name":"Religious Store"},"shop/scuba_diving":{"icon":"swimming","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"scuba_diving"},"name":"Scuba Diving Shop"},"shop/seafood":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fishmonger"],"tags":{"shop":"seafood"},"name":"Seafood Shop"},"shop/second_hand":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"shoes"},"name":"Shoe Store"},"shop/sports":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"sports"},"name":"Sporting Goods Store"},"shop/stationery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["card","paper"],"tags":{"shop":"stationery"},"name":"Stationery Store"},"shop/storage_rental":{"icon":"shop","fields":["name","operator","address","building","opening_hours"],"geometry":["point","area"],"tags":{"shop":"storage_rental"},"name":"Storage Rental"},"shop/supermarket":{"icon":"grocery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["grocery","store","shop"],"tags":{"shop":"supermarket"},"name":"Supermarket"},"shop/tailor":{"icon":"clothing-store","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"shop":"tailor"},"name":"Tailor"},"shop/tattoo":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tattoo"},"name":"Tattoo Parlor"},"shop/tea":{"icon":"teahouse","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tea"},"name":"Tea Store"},"shop/ticket":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"ticket"},"name":"Ticket Seller"},"shop/tobacco":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tobacco"},"name":"Tobacco Shop"},"shop/toys":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"toys"},"name":"Toy Store"},"shop/travel_agency":{"icon":"suitcase","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"travel_agency"},"name":"Travel Agency"},"shop/tyres":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tyres"},"name":"Tire Store"},"shop/vacuum_cleaner":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"vacuum_cleaner"},"name":"Vacuum Cleaner Store"},"shop/variety_store":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"variety_store"},"name":"Variety Store"},"shop/video_games":{"icon":"gaming","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"video_games"},"name":"Video Game Store"},"shop/video":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["DVD"],"tags":{"shop":"video"},"name":"Video Store"},"shop/watches":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"watches"},"name":"Watches Shop"},"shop/water_sports":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"water_sports"},"name":"Watersport/Swim Shop"},"shop/weapons":{"icon":"shop","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"window_blind"},"name":"Window Blind Store"},"shop/wine":{"icon":"alcohol-shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"wine"},"name":"Wine Shop"},"tourism":{"icon":"attraction","fields":["name","tourism"],"geometry":["point","vertex","area"],"tags":{"tourism":"*"},"name":"Tourism"},"tourism/alpine_hut":{"icon":"lodging","fields":["name","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"alpine_hut"},"name":"Alpine Hut"},"tourism/apartment":{"icon":"lodging","fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"apartment"},"name":"Guest Apartment / Condo"},"tourism/aquarium":{"icon":"aquarium","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fish","sea","water"],"tags":{"tourism":"aquarium"},"name":"Aquarium"},"tourism/artwork":{"icon":"art-gallery","fields":["name","artwork_type","artist"],"geometry":["point","vertex","area"],"tags":{"tourism":"artwork"},"terms":["mural","sculpture","statue"],"name":"Artwork"},"tourism/attraction":{"icon":"monument","fields":["name","operator","address"],"geometry":["point","vertex","area"],"tags":{"tourism":"attraction"},"name":"Tourist Attraction"},"tourism/camp_site":{"icon":"campsite","fields":["name","operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"terms":["tent","rv"],"tags":{"tourism":"camp_site"},"name":"Campground"},"tourism/caravan_site":{"icon":"bus","fields":["name","operator","address","capacity","fee","sanitary_dump_station","power_supply","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"terms":["Motor Home","Camper"],"tags":{"tourism":"caravan_site"},"name":"RV Park"},"tourism/chalet":{"icon":"lodging","fields":["name","operator","address","building_area","smoking","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"chalet"},"name":"Chalet"},"tourism/gallery":{"icon":"art-gallery","fields":["name","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":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"guest_house"},"terms":["B&B","Bed and Breakfast"],"name":"Guest House"},"tourism/hostel":{"icon":"lodging","fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"hostel"},"name":"Hostel"},"tourism/hotel":{"icon":"lodging","fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"hotel"},"name":"Hotel"},"tourism/information":{"icon":"information","fields":["information","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information"},"name":"Information"},"tourism/information/board":{"icon":"information","fields":["name","operator","board_type"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"board"},"reference":{"key":"information","value":"board"},"name":"Information Board"},"tourism/information/guidepost":{"icon":"information","fields":["operator","ref"],"geometry":["point","vertex"],"terms":["signpost"],"tags":{"tourism":"information","information":"guidepost"},"reference":{"key":"information","value":"guidepost"},"name":"Guidepost"},"tourism/information/map":{"icon":"information","fields":["operator","map_type","map_size"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"map"},"reference":{"key":"information","value":"map"},"name":"Map"},"tourism/information/office":{"icon":"information","fields":["name","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information","information":"office"},"reference":{"key":"information","value":"office"},"name":"Tourist Information Office"},"tourism/motel":{"icon":"lodging","fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"motel"},"name":"Motel"},"tourism/museum":{"icon":"museum","fields":["name","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":"picnic-site","fields":["name","operator","address","smoking"],"geometry":["point","vertex","area"],"terms":["camp"],"tags":{"tourism":"picnic_site"},"name":"Picnic Site"},"tourism/theme_park":{"icon":"amusement-park","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"tourism":"theme_park"},"name":"Theme Park"},"tourism/viewpoint":{"icon":"poi-binoculars","geometry":["point","vertex"],"tags":{"tourism":"viewpoint"},"name":"Viewpoint"},"tourism/zoo":{"icon":"zoo","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["animal"],"tags":{"tourism":"zoo"},"name":"Zoo"},"traffic_calming":{"icon":"poi-warning","fields":["traffic_calming","parallel_direction"],"geometry":["vertex","line"],"tags":{"traffic_calming":"*"},"terms":["bump","hump","slow","speed"],"name":"Traffic Calming"},"traffic_calming/bump":{"icon":"poi-warning","fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["hump","speed","slow"],"tags":{"traffic_calming":"bump"},"name":"Speed Bump"},"traffic_calming/chicane":{"icon":"poi-warning","fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["driveway link","speed","slow"],"tags":{"traffic_calming":"chicane"},"name":"Traffic Chicane"},"traffic_calming/choker":{"icon":"poi-warning","fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"choker"},"name":"Traffic Choker"},"traffic_calming/cushion":{"icon":"poi-warning","fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["bump","hump","speed","slow"],"tags":{"traffic_calming":"cushion"},"name":"Speed Cushion"},"traffic_calming/dip":{"icon":"poi-warning","fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"dip"},"name":"Dip"},"traffic_calming/hump":{"icon":"poi-warning","fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["bump","speed","slow"],"tags":{"traffic_calming":"hump"},"name":"Speed Hump"},"traffic_calming/island":{"icon":"poi-warning","geometry":["vertex"],"terms":["circle","roundabout","slow"],"tags":{"traffic_calming":"island"},"name":"Traffic Island"},"traffic_calming/rumble_strip":{"icon":"poi-warning","fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["audible lines","sleeper lines","growlers"],"tags":{"traffic_calming":"rumble_strip"},"name":"Rumble Strip"},"traffic_calming/table":{"icon":"poi-warning","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":["name","boundary"]},"type/boundary/administrative":{"icon":"boundary","fields":["name","admin_level"],"geometry":["relation"],"tags":{"type":"boundary","boundary":"administrative"},"reference":{"key":"boundary","value":"administrative"},"name":"Administrative Boundary"},"type/restriction":{"geometry":["relation"],"tags":{"type":"restriction"},"name":"Restriction","icon":"restriction","fields":["name","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":["name","route_master","ref","operator","network"]},"type/route":{"geometry":["relation"],"tags":{"type":"route"},"name":"Route","icon":"route","fields":["name","route","ref_route","operator","network"]},"type/route/bicycle":{"geometry":["relation"],"tags":{"type":"route","route":"bicycle"},"name":"Cycle Route","icon":"route-bicycle","fields":["name","ref_route","network_bicycle","cycle_network"]},"type/route/bus":{"geometry":["relation"],"tags":{"type":"route","route":"bus"},"name":"Bus Route","icon":"route-bus","fields":["name","ref_route","operator","network"]},"type/route/detour":{"geometry":["relation"],"tags":{"type":"route","route":"detour"},"name":"Detour Route","icon":"route-detour","fields":["name","ref_route"]},"type/route/ferry":{"geometry":["relation"],"tags":{"type":"route","route":"ferry"},"name":"Ferry Route","icon":"route-ferry","fields":["name","ref_route","operator","network"]},"type/route/foot":{"geometry":["relation"],"tags":{"type":"route","route":"foot"},"name":"Foot Route","icon":"route-foot","fields":["name","ref_route","operator","network_foot"]},"type/route/hiking":{"geometry":["relation"],"tags":{"type":"route","route":"hiking"},"name":"Hiking Route","icon":"route-foot","fields":["name","ref_route","operator","network_foot"]},"type/route/horse":{"geometry":["relation"],"tags":{"type":"route","route":"horse"},"name":"Riding Route","icon":"route-horse","fields":["name","ref_route","operator","network_horse"]},"type/route/pipeline":{"geometry":["relation"],"tags":{"type":"route","route":"pipeline"},"name":"Pipeline Route","icon":"route-pipeline","fields":["name","ref_route","operator"]},"type/route/power":{"geometry":["relation"],"tags":{"type":"route","route":"power"},"name":"Power Route","icon":"route-power","fields":["name","ref_route","operator"]},"type/route/road":{"geometry":["relation"],"tags":{"type":"route","route":"road"},"name":"Road Route","icon":"route-road","fields":["name","ref_route","network_road"]},"type/route/train":{"geometry":["relation"],"tags":{"type":"route","route":"train"},"name":"Train Route","icon":"route-train","fields":["name","ref_route","operator","network"]},"type/route/tram":{"geometry":["relation"],"tags":{"type":"route","route":"tram"},"name":"Tram Route","icon":"route-tram","fields":["name","ref_route","operator","network"]},"type/site":{"geometry":["relation"],"tags":{"type":"site"},"name":"Site","icon":"relation","fields":["name","site"]},"vertex":{"name":"Other","tags":{},"fields":["name"],"geometry":["vertex"],"matchScore":0.1},"waterway/boatyard":{"icon":"harbor","fields":["name","operator"],"geometry":["area","vertex","point"],"tags":{"waterway":"boatyard"},"name":"Boatyard"},"waterway/canal":{"icon":"waterway-canal","fields":["name","width"],"geometry":["line"],"tags":{"waterway":"canal"},"name":"Canal"},"waterway/dam":{"icon":"dam","geometry":["point","vertex","line","area"],"fields":["name"],"tags":{"waterway":"dam"},"name":"Dam"},"waterway/ditch":{"icon":"waterway-ditch","fields":["tunnel_waterway"],"geometry":["line"],"tags":{"waterway":"ditch"},"name":"Ditch"},"waterway/dock":{"icon":"harbor","fields":["name","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_waterway"],"geometry":["line"],"tags":{"waterway":"drain"},"name":"Drain"},"waterway/fuel":{"icon":"fuel","fields":["name","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":["name","tunnel_waterway","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":{"icon":"poi-storage-tank","fields":["name","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":["name","tunnel_waterway","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":"drinking-water","geometry":["area","vertex","point"],"tags":{"waterway":"water_point"},"name":"Marine Drinking Water"},"waterway/waterfall":{"icon":"water","fields":["name","height","width"],"geometry":["vertex"],"terms":["fall"],"tags":{"waterway":"waterfall"},"name":"Waterfall"},"waterway/weir":{"icon":"dam","geometry":["vertex","line"],"tags":{"waterway":"weir"},"name":"Weir"},"amenity/arts_centre/Świetlica wiejska":{"tags":{"name":"Świetlica wiejska","amenity":"arts_centre"},"name":"Świetlica wiejska","icon":"theatre","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/arts_centre/Дом культуры":{"tags":{"name":"Дом культуры","amenity":"arts_centre"},"name":"Дом культуры","icon":"theatre","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/bank/ABANCA":{"tags":{"name":"ABANCA","amenity":"bank"},"name":"ABANCA","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ASB Bank":{"tags":{"name":"ASB Bank","amenity":"bank"},"name":"ASB Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ATB Financial":{"tags":{"name":"ATB Financial","amenity":"bank"},"name":"ATB Financial","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Agribank":{"tags":{"name":"Agribank","amenity":"bank"},"name":"Agribank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Akbank":{"tags":{"name":"Akbank","amenity":"bank"},"name":"Akbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Allahabad Bank":{"tags":{"name":"Allahabad Bank","amenity":"bank"},"name":"Allahabad Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Allied Bank":{"tags":{"name":"Allied Bank","amenity":"bank"},"name":"Allied Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Andhra Bank":{"tags":{"name":"Andhra Bank","amenity":"bank"},"name":"Andhra Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Antonveneta":{"tags":{"name":"Antonveneta","amenity":"bank"},"name":"Antonveneta","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Asia United Bank":{"tags":{"name":"Asia United Bank","amenity":"bank"},"name":"Asia United Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Askari Bank":{"tags":{"name":"Askari Bank","amenity":"bank"},"name":"Askari Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Associated Bank":{"tags":{"name":"Associated Bank","amenity":"bank"},"name":"Associated Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BAC":{"tags":{"name":"BAC","amenity":"bank"},"name":"BAC","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBBank":{"tags":{"name":"BBBank","amenity":"bank"},"name":"BBBank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Bancomer":{"tags":{"name":"BBVA Bancomer","amenity":"bank"},"name":"BBVA Bancomer","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Compass":{"tags":{"name":"BBVA Compass","amenity":"bank"},"name":"BBVA Compass","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Continental":{"tags":{"name":"BBVA Continental","amenity":"bank"},"name":"BBVA Continental","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Francés":{"tags":{"name":"BBVA Francés","amenity":"bank"},"name":"BBVA Francés","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCA":{"tags":{"name":"BCA","amenity":"bank"},"name":"BCA","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCP":{"tags":{"name":"BCP","amenity":"bank"},"name":"BCP","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BGŻ BNP Paribas":{"tags":{"name":"BGŻ BNP Paribas","amenity":"bank"},"name":"BGŻ BNP Paribas","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMCE":{"tags":{"name":"BMCE","amenity":"bank"},"name":"BMCE","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMN":{"tags":{"name":"BMN","amenity":"bank"},"name":"BMN","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMO Harris Bank":{"tags":{"name":"BMO Harris Bank","amenity":"bank"},"name":"BMO Harris Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNA":{"tags":{"name":"BNA","amenity":"bank"},"name":"BNA","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNI":{"tags":{"name":"BNI","amenity":"bank"},"name":"BNI","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BPH":{"tags":{"name":"BPH","amenity":"bank"},"name":"BPH","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BPI Family Savings Bank":{"tags":{"name":"BPI Family Savings Bank","amenity":"bank"},"name":"BPI Family Savings Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BRED":{"tags":{"name":"BRED","amenity":"bank"},"name":"BRED","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BRI":{"tags":{"name":"BRI","amenity":"bank"},"name":"BRI","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banc Sabadell":{"tags":{"name":"Banc Sabadell","amenity":"bank"},"name":"Banc Sabadell","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca March":{"tags":{"name":"Banca March","amenity":"bank"},"name":"Banca March","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Milano":{"tags":{"name":"Banca Popolare di Milano","amenity":"bank"},"name":"Banca Popolare di Milano","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Novara":{"tags":{"name":"Banca Popolare di Novara","amenity":"bank"},"name":"Banca Popolare di Novara","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Sondrio":{"tags":{"name":"Banca Popolare di Sondrio","amenity":"bank"},"name":"Banca Popolare di Sondrio","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Verona":{"tags":{"name":"Banca Popolare di Verona","amenity":"bank"},"name":"Banca Popolare di Verona","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Românească":{"tags":{"name":"Banca Românească","amenity":"bank"},"name":"Banca Românească","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Sella":{"tags":{"name":"Banca Sella","amenity":"bank"},"name":"Banca Sella","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Agrario":{"tags":{"name":"Banco Agrario","amenity":"bank"},"name":"Banco Agrario","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Azteca":{"tags":{"name":"Banco Azteca","amenity":"bank"},"name":"Banco Azteca","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Continental":{"tags":{"name":"Banco Continental","amenity":"bank"},"name":"Banco Continental","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Fassil":{"tags":{"name":"Banco Fassil","amenity":"bank"},"name":"Banco Fassil","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco General":{"tags":{"name":"Banco General","amenity":"bank"},"name":"Banco General","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Industrial":{"tags":{"name":"Banco Industrial","amenity":"bank"},"name":"Banco Industrial","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Internacional":{"tags":{"name":"Banco Internacional","amenity":"bank"},"name":"Banco Internacional","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Nacional":{"tags":{"name":"Banco Nacional","amenity":"bank"},"name":"Banco Nacional","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Pichincha":{"tags":{"name":"Banco Pichincha","amenity":"bank"},"name":"Banco Pichincha","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Sabadell":{"tags":{"name":"Banco Sabadell","amenity":"bank"},"name":"Banco Sabadell","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Sol":{"tags":{"name":"Banco Sol","amenity":"bank"},"name":"Banco Sol","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Bogotá":{"tags":{"name":"Banco de Bogotá","amenity":"bank"},"name":"Banco de Bogotá","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Occidente":{"tags":{"name":"Banco de Occidente","amenity":"bank"},"name":"Banco de Occidente","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Venezuela":{"tags":{"name":"Banco de Venezuela","amenity":"bank"},"name":"Banco de Venezuela","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de la Nación Argentina":{"tags":{"name":"Banco de la Nación Argentina","amenity":"bank"},"name":"Banco de la Nación Argentina","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco di Napoli":{"tags":{"name":"Banco di Napoli","amenity":"bank"},"name":"Banco di Napoli","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco di Sardegna":{"tags":{"name":"Banco di Sardegna","amenity":"bank"},"name":"Banco di Sardegna","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco do Nordeste":{"tags":{"name":"Banco do Nordeste","amenity":"bank"},"name":"Banco do Nordeste","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bangkok Bank":{"tags":{"name":"Bangkok Bank","amenity":"bank"},"name":"Bangkok Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Al Habib":{"tags":{"name":"Bank Al Habib","amenity":"bank"},"name":"Bank Al Habib","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Alfalah":{"tags":{"name":"Bank Alfalah","amenity":"bank"},"name":"Bank Alfalah","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BCA":{"tags":{"name":"Bank BCA","amenity":"bank"},"name":"Bank BCA","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BNI":{"tags":{"name":"Bank BNI","amenity":"bank"},"name":"Bank BNI","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BPH":{"tags":{"name":"Bank BPH","amenity":"bank"},"name":"Bank BPH","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Danamon":{"tags":{"name":"Bank Danamon","amenity":"bank"},"name":"Bank Danamon","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Mega":{"tags":{"name":"Bank Mega","amenity":"bank"},"name":"Bank Mega","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Zachodni WBK":{"tags":{"name":"Bank Zachodni WBK","amenity":"bank"},"name":"Bank Zachodni WBK","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Africa":{"tags":{"name":"Bank of Africa","amenity":"bank"},"name":"Bank of Africa","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Baroda":{"tags":{"name":"Bank of Baroda","amenity":"bank"},"name":"Bank of Baroda","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Ceylon":{"tags":{"name":"Bank of Ceylon","amenity":"bank"},"name":"Bank of Ceylon","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of China":{"tags":{"name":"Bank of China","amenity":"bank"},"name":"Bank of China","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Commerce":{"tags":{"name":"Bank of Commerce","amenity":"bank"},"name":"Bank of Commerce","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of India":{"tags":{"name":"Bank of India","amenity":"bank"},"name":"Bank of India","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of New Zealand":{"tags":{"name":"Bank of New Zealand","amenity":"bank"},"name":"Bank of New Zealand","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banner Bank":{"tags":{"name":"Banner Bank","amenity":"bank"},"name":"Banner Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banque Atlantique":{"tags":{"name":"Banque Atlantique","amenity":"bank"},"name":"Banque Atlantique","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banrisul":{"tags":{"name":"Banrisul","amenity":"bank"},"name":"Banrisul","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banrural":{"tags":{"name":"Banrural","amenity":"bank"},"name":"Banrural","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bcc":{"tags":{"name":"Bcc","amenity":"bank"},"name":"Bcc","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Budapest Bank":{"tags":{"name":"Budapest Bank","amenity":"bank"},"name":"Budapest Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CBAO":{"tags":{"name":"CBAO","amenity":"bank"},"name":"CBAO","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CEC Bank":{"tags":{"name":"CEC Bank","amenity":"bank"},"name":"CEC Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CGD":{"tags":{"name":"CGD","amenity":"bank"},"name":"CGD","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIB Bank":{"tags":{"name":"CIB Bank","amenity":"bank"},"name":"CIB Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIMB Bank":{"tags":{"name":"CIMB Bank","amenity":"bank"},"name":"CIMB Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CNEP":{"tags":{"name":"CNEP","amenity":"bank"},"name":"CNEP","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caisse Desjardins":{"tags":{"name":"Caisse Desjardins","amenity":"bank"},"name":"Caisse Desjardins","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CaixaBank":{"tags":{"name":"CaixaBank","amenity":"bank"},"name":"CaixaBank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja España":{"tags":{"name":"Caja España","amenity":"bank"},"name":"Caja España","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Rural de Jaén":{"tags":{"name":"Caja Rural de Jaén","amenity":"bank"},"name":"Caja Rural de Jaén","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CajaSur":{"tags":{"name":"CajaSur","amenity":"bank"},"name":"CajaSur","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Carige":{"tags":{"name":"Carige","amenity":"bank"},"name":"Carige","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cariparma":{"tags":{"name":"Cariparma","amenity":"bank"},"name":"Cariparma","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CatalunyaCaixa":{"tags":{"name":"CatalunyaCaixa","amenity":"bank"},"name":"CatalunyaCaixa","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Central Bank of India":{"tags":{"name":"Central Bank of India","amenity":"bank"},"name":"Central Bank of India","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Chase":{"tags":{"name":"Chase","amenity":"bank"},"name":"Chase","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/China Bank Savings":{"tags":{"name":"China Bank Savings","amenity":"bank"},"name":"China Bank Savings","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/China Construction Bank":{"tags":{"name":"China Construction Bank","amenity":"bank"},"name":"China Construction Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Clydesdale Bank":{"tags":{"name":"Clydesdale Bank","amenity":"bank"},"name":"Clydesdale Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Columbia Bank":{"tags":{"name":"Columbia Bank","amenity":"bank"},"name":"Columbia Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Comerica Bank":{"tags":{"name":"Comerica Bank","amenity":"bank"},"name":"Comerica Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commerce Bank":{"tags":{"name":"Commerce Bank","amenity":"bank"},"name":"Commerce Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commercial Bank":{"tags":{"name":"Commercial Bank","amenity":"bank"},"name":"Commercial Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Corporation Bank":{"tags":{"name":"Corporation Bank","amenity":"bank"},"name":"Corporation Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credem":{"tags":{"name":"Credem","amenity":"bank"},"name":"Credem","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credicoop":{"tags":{"name":"Credicoop","amenity":"bank"},"name":"Credicoop","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crelan":{"tags":{"name":"Crelan","amenity":"bank"},"name":"Crelan","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédito Agrícola":{"tags":{"name":"Crédito Agrícola","amenity":"bank"},"name":"Crédito Agrícola","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cбербанк":{"tags":{"name":"Cбербанк","amenity":"bank"},"name":"Cбербанк","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Denizbank":{"tags":{"name":"Denizbank","amenity":"bank"},"name":"Denizbank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Desjardins":{"tags":{"name":"Desjardins","amenity":"bank"},"name":"Desjardins","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Dubai Islamic Bank":{"tags":{"name":"Dubai Islamic Bank","amenity":"bank"},"name":"Dubai Islamic Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/EastWest Bank":{"tags":{"name":"EastWest Bank","amenity":"bank"},"name":"EastWest Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Express Union":{"tags":{"name":"Express Union","amenity":"bank"},"name":"Express Union","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Federal Bank":{"tags":{"name":"Federal Bank","amenity":"bank"},"name":"Federal Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Finansbank":{"tags":{"name":"Finansbank","amenity":"bank"},"name":"Finansbank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/First Bank":{"tags":{"name":"First Bank","amenity":"bank"},"name":"First Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/First Citizens Bank":{"tags":{"name":"First Citizens Bank","amenity":"bank"},"name":"First Citizens Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Galicia":{"tags":{"name":"Galicia","amenity":"bank"},"name":"Galicia","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Garanti":{"tags":{"name":"Garanti","amenity":"bank"},"name":"Garanti","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Garanti Bankası":{"tags":{"name":"Garanti Bankası","amenity":"bank"},"name":"Garanti Bankası","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Groupama":{"tags":{"name":"Groupama","amenity":"bank"},"name":"Groupama","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HNB":{"tags":{"name":"HNB","amenity":"bank"},"name":"HNB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Halkbank":{"tags":{"name":"Halkbank","amenity":"bank"},"name":"Halkbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Hong Leong Bank":{"tags":{"name":"Hong Leong Bank","amenity":"bank"},"name":"Hong Leong Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Hrvatska poštanska banka":{"tags":{"name":"Hrvatska poštanska banka","amenity":"bank"},"name":"Hrvatska poštanska banka","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Huntington Bank":{"tags":{"name":"Huntington Bank","amenity":"bank"},"name":"Huntington Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ICBC":{"tags":{"name":"ICBC","amenity":"bank"},"name":"ICBC","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/IDBI Bank":{"tags":{"name":"IDBI Bank","amenity":"bank"},"name":"IDBI Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Indian Bank":{"tags":{"name":"Indian Bank","amenity":"bank"},"name":"Indian Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Indian Overseas Bank":{"tags":{"name":"Indian Overseas Bank","amenity":"bank"},"name":"Indian Overseas Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Interbank":{"tags":{"name":"Interbank","amenity":"bank"},"name":"Interbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/K&H Bank":{"tags":{"name":"K&H Bank","amenity":"bank"},"name":"K&H Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kasa Stefczyka":{"tags":{"name":"Kasa Stefczyka","amenity":"bank"},"name":"Kasa Stefczyka","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kutxabank":{"tags":{"name":"Kutxabank","amenity":"bank"},"name":"Kutxabank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Laboral Kutxa":{"tags":{"name":"Laboral Kutxa","amenity":"bank"},"name":"Laboral Kutxa","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Liberbank":{"tags":{"name":"Liberbank","amenity":"bank"},"name":"Liberbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/MCB":{"tags":{"name":"MCB","amenity":"bank"},"name":"MCB","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/MCB Bank":{"tags":{"name":"MCB Bank","amenity":"bank"},"name":"MCB Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/MONETA Money Bank":{"tags":{"name":"MONETA Money Bank","amenity":"bank"},"name":"MONETA Money Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Macro":{"tags":{"name":"Macro","amenity":"bank"},"name":"Macro","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Meezan Bank":{"tags":{"name":"Meezan Bank","amenity":"bank"},"name":"Meezan Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Metro Bank":{"tags":{"name":"Metro Bank","amenity":"bank"},"name":"Metro Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Millennium BCP":{"tags":{"name":"Millennium BCP","amenity":"bank"},"name":"Millennium BCP","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Montepio":{"tags":{"name":"Montepio","amenity":"bank"},"name":"Montepio","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/NSB":{"tags":{"name":"NSB","amenity":"bank"},"name":"NSB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Novo Banco":{"tags":{"name":"Novo Banco","amenity":"bank"},"name":"Novo Banco","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Occidental de Descuento":{"tags":{"name":"Occidental de Descuento","amenity":"bank"},"name":"Occidental de Descuento","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/One Network Bank":{"tags":{"name":"One Network Bank","amenity":"bank"},"name":"One Network Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PKO":{"tags":{"name":"PKO","amenity":"bank"},"name":"PKO","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PNC":{"tags":{"name":"PNC","amenity":"bank"},"name":"PNC","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Patagonia":{"tags":{"name":"Patagonia","amenity":"bank"},"name":"Patagonia","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Philippine National Bank":{"tags":{"name":"Philippine National Bank","amenity":"bank"},"name":"Philippine National Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Piraeus Bank":{"tags":{"name":"Piraeus Bank","amenity":"bank"},"name":"Piraeus Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Popular":{"tags":{"name":"Popular","amenity":"bank"},"name":"Popular","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Postbank Finanzcenter":{"tags":{"name":"Postbank Finanzcenter","amenity":"bank"},"name":"Postbank Finanzcenter","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Public Bank":{"tags":{"name":"Public Bank","amenity":"bank"},"name":"Public Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Punjab National Bank":{"tags":{"name":"Punjab National Bank","amenity":"bank"},"name":"Punjab National Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RBC Financial Group":{"tags":{"name":"RBC Financial Group","amenity":"bank"},"name":"RBC Financial Group","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RCBC Savings Bank":{"tags":{"name":"RCBC Savings Bank","amenity":"bank"},"name":"RCBC Savings Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Raiffeisen Polbank":{"tags":{"name":"Raiffeisen Polbank","amenity":"bank"},"name":"Raiffeisen Polbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Republic Bank":{"tags":{"name":"Republic Bank","amenity":"bank"},"name":"Republic Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Royal Bank of Canada":{"tags":{"name":"Royal Bank of Canada","amenity":"bank"},"name":"Royal Bank of Canada","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SNS Bank":{"tags":{"name":"SNS Bank","amenity":"bank"},"name":"SNS Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sabadell":{"tags":{"name":"Sabadell","amenity":"bank"},"name":"Sabadell","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sampath Bank":{"tags":{"name":"Sampath Bank","amenity":"bank"},"name":"Sampath Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander Río":{"tags":{"name":"Santander Río","amenity":"bank"},"name":"Santander Río","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sicredi":{"tags":{"name":"Sicredi","amenity":"bank"},"name":"Sicredi","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Stanbic Bank":{"tags":{"name":"Stanbic Bank","amenity":"bank"},"name":"Stanbic Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Standard Chartered":{"tags":{"name":"Standard Chartered","amenity":"bank"},"name":"Standard Chartered","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Standard Chartered Bank":{"tags":{"name":"Standard Chartered Bank","amenity":"bank"},"name":"Standard Chartered Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Supervielle":{"tags":{"name":"Supervielle","amenity":"bank"},"name":"Supervielle","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Syndicate Bank":{"tags":{"name":"Syndicate Bank","amenity":"bank"},"name":"Syndicate Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TCF Bank":{"tags":{"name":"TCF Bank","amenity":"bank"},"name":"TCF Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TEB":{"tags":{"name":"TEB","amenity":"bank"},"name":"TEB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Takarékszövetkezet":{"tags":{"name":"Takarékszövetkezet","amenity":"bank"},"name":"Takarékszövetkezet","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Türkiye İş Bankası":{"tags":{"name":"Türkiye İş Bankası","amenity":"bank"},"name":"Türkiye İş Bankası","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UCO Bank":{"tags":{"name":"UCO Bank","amenity":"bank"},"name":"UCO Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UOB":{"tags":{"name":"UOB","amenity":"bank"},"name":"UOB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Umpqua Bank":{"tags":{"name":"Umpqua Bank","amenity":"bank"},"name":"Umpqua Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Unicaja Banco":{"tags":{"name":"Unicaja Banco","amenity":"bank"},"name":"Unicaja Banco","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/United Bank":{"tags":{"name":"United Bank","amenity":"bank"},"name":"United Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Vakıfbank":{"tags":{"name":"Vakıfbank","amenity":"bank"},"name":"Vakıfbank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Veneto Banca":{"tags":{"name":"Veneto Banca","amenity":"bank"},"name":"Veneto Banca","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Vijaya Bank":{"tags":{"name":"Vijaya Bank","amenity":"bank"},"name":"Vijaya Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volks- und Raiffeisenbank":{"tags":{"name":"Volks- und Raiffeisenbank","amenity":"bank"},"name":"Volks- und Raiffeisenbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volksbank Mittelhessen":{"tags":{"name":"Volksbank Mittelhessen","amenity":"bank"},"name":"Volksbank Mittelhessen","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volksbank Raiffeisenbank":{"tags":{"name":"Volksbank Raiffeisenbank","amenity":"bank"},"name":"Volksbank Raiffeisenbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Washington Federal":{"tags":{"name":"Washington Federal","amenity":"bank"},"name":"Washington Federal","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Yorkshire Building Society":{"tags":{"name":"Yorkshire Building Society","amenity":"bank"},"name":"Yorkshire Building Society","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Zagrebačka banka":{"tags":{"name":"Zagrebačka banka","amenity":"bank"},"name":"Zagrebačka banka","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ziraat Bankası":{"tags":{"name":"Ziraat Bankası","amenity":"bank"},"name":"Ziraat Bankası","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/mBank":{"tags":{"name":"mBank","amenity":"bank"},"name":"mBank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/İş Bankası":{"tags":{"name":"İş Bankası","amenity":"bank"},"name":"İş Bankası","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Εθνική Τράπεζα":{"tags":{"name":"Εθνική Τράπεζα","amenity":"bank"},"name":"Εθνική Τράπεζα","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Πειραιώς":{"tags":{"name":"Πειραιώς","amenity":"bank"},"name":"Πειραιώς","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Τράπεζα Πειραιώς":{"tags":{"name":"Τράπεζα Πειραιώς","amenity":"bank"},"name":"Τράπεζα Πειραιώς","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Авангард":{"tags":{"name":"Авангард","amenity":"bank"},"name":"Авангард","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Альфа-Банк":{"tags":{"name":"Альфа-Банк","amenity":"bank"},"name":"Альфа-Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Банк Москвы":{"tags":{"name":"Банк Москвы","amenity":"bank"},"name":"Банк Москвы","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Банка ДСК":{"tags":{"name":"Банка ДСК","amenity":"bank"},"name":"Банка ДСК","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Белагропромбанк":{"tags":{"name":"Белагропромбанк","amenity":"bank"},"name":"Белагропромбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Беларусбанк":{"tags":{"name":"Беларусбанк","amenity":"bank"},"name":"Беларусбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Белинвестбанк":{"tags":{"name":"Белинвестбанк","amenity":"bank"},"name":"Белинвестбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Бинбанк":{"tags":{"name":"Бинбанк","amenity":"bank"},"name":"Бинбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ВТБ":{"tags":{"name":"ВТБ","amenity":"bank"},"name":"ВТБ","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Возрождение":{"tags":{"name":"Возрождение","amenity":"bank"},"name":"Возрождение","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Газпромбанк":{"tags":{"name":"Газпромбанк","amenity":"bank"},"name":"Газпромбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Генбанк":{"tags":{"name":"Генбанк","amenity":"bank"},"name":"Генбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Казкоммерцбанк":{"tags":{"name":"Казкоммерцбанк","amenity":"bank"},"name":"Казкоммерцбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/МДМ Банк":{"tags":{"name":"МДМ Банк","amenity":"bank"},"name":"МДМ Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Московский индустриальный банк":{"tags":{"name":"Московский индустриальный банк","amenity":"bank"},"name":"Московский индустриальный банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Мособлбанк":{"tags":{"name":"Мособлбанк","amenity":"bank"},"name":"Мособлбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Народный банк":{"tags":{"name":"Народный банк","amenity":"bank"},"name":"Народный банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ОТП Банк":{"tags":{"name":"ОТП Банк","amenity":"bank"},"name":"ОТП Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Открытие":{"tags":{"name":"Открытие","amenity":"bank"},"name":"Открытие","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ощадбанк":{"tags":{"name":"Ощадбанк","amenity":"bank"},"name":"Ощадбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ПУМБ":{"tags":{"name":"ПУМБ","amenity":"bank"},"name":"ПУМБ","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Почта Банк":{"tags":{"name":"Почта Банк","amenity":"bank"},"name":"Почта Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ПриватБанк":{"tags":{"name":"ПриватБанк","amenity":"bank"},"name":"ПриватБанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Приватбанк":{"tags":{"name":"Приватбанк","amenity":"bank"},"name":"Приватбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Приднестровский Сбербанк":{"tags":{"name":"Приднестровский Сбербанк","amenity":"bank"},"name":"Приднестровский Сбербанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Приорбанк":{"tags":{"name":"Приорбанк","amenity":"bank"},"name":"Приорбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Промсвязьбанк":{"tags":{"name":"Промсвязьбанк","amenity":"bank"},"name":"Промсвязьбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/РНКБ":{"tags":{"name":"РНКБ","amenity":"bank"},"name":"РНКБ","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзен":{"tags":{"name":"Райффайзен","amenity":"bank"},"name":"Райффайзен","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзен Банк Аваль":{"tags":{"name":"Райффайзен Банк Аваль","amenity":"bank"},"name":"Райффайзен Банк Аваль","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзенбанк":{"tags":{"name":"Райффайзенбанк","amenity":"bank"},"name":"Райффайзенбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Росбанк":{"tags":{"name":"Росбанк","amenity":"bank"},"name":"Росбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Россельхозбанк":{"tags":{"name":"Россельхозбанк","amenity":"bank"},"name":"Россельхозбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Русский стандарт":{"tags":{"name":"Русский стандарт","amenity":"bank"},"name":"Русский стандарт","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Сбербанк":{"tags":{"name":"Сбербанк","amenity":"bank"},"name":"Сбербанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Совкомбанк":{"tags":{"name":"Совкомбанк","amenity":"bank"},"name":"Совкомбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/УкрСиббанк":{"tags":{"name":"УкрСиббанк","amenity":"bank"},"name":"УкрСиббанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Укрсоцбанк":{"tags":{"name":"Укрсоцбанк","amenity":"bank"},"name":"Укрсоцбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Уралсиб":{"tags":{"name":"Уралсиб","amenity":"bank"},"name":"Уралсиб","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Хоум Кредит":{"tags":{"name":"Хоум Кредит","amenity":"bank"},"name":"Хоум Кредит","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/בנק הפועלים":{"tags":{"name":"בנק הפועלים","amenity":"bank"},"name":"בנק הפועלים","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/בנק לאומי":{"tags":{"name":"בנק לאומי","amenity":"bank"},"name":"בנק לאומי","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک":{"tags":{"name":"بانک","amenity":"bank"},"name":"بانک","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک آینده":{"tags":{"name":"بانک آینده","amenity":"bank"},"name":"بانک آینده","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک اقتصاد نوین":{"tags":{"name":"بانک اقتصاد نوین","amenity":"bank"},"name":"بانک اقتصاد نوین","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک انصار":{"tags":{"name":"بانک انصار","amenity":"bank"},"name":"بانک انصار","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک تجارت":{"tags":{"name":"بانک تجارت","amenity":"bank"},"name":"بانک تجارت","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک رفاه":{"tags":{"name":"بانک رفاه","amenity":"bank"},"name":"بانک رفاه","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک رفاه کارگران":{"tags":{"name":"بانک رفاه کارگران","amenity":"bank"},"name":"بانک رفاه کارگران","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک سپه":{"tags":{"name":"بانک سپه","amenity":"bank"},"name":"بانک سپه","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک شهر":{"tags":{"name":"بانک شهر","amenity":"bank"},"name":"بانک شهر","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک صادرات":{"tags":{"name":"بانک صادرات","amenity":"bank"},"name":"بانک صادرات","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک قوامین":{"tags":{"name":"بانک قوامین","amenity":"bank"},"name":"بانک قوامین","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک مسکن":{"tags":{"name":"بانک مسکن","amenity":"bank"},"name":"بانک مسکن","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک ملت":{"tags":{"name":"بانک ملت","amenity":"bank"},"name":"بانک ملت","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک ملی":{"tags":{"name":"بانک ملی","amenity":"bank"},"name":"بانک ملی","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک ملی ایران":{"tags":{"name":"بانک ملی ایران","amenity":"bank"},"name":"بانک ملی ایران","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک مهر اقتصاد":{"tags":{"name":"بانک مهر اقتصاد","amenity":"bank"},"name":"بانک مهر اقتصاد","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک پارسیان":{"tags":{"name":"بانک پارسیان","amenity":"bank"},"name":"بانک پارسیان","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک پاسارگاد":{"tags":{"name":"بانک پاسارگاد","amenity":"bank"},"name":"بانک پاسارگاد","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک کشاورزی":{"tags":{"name":"بانک کشاورزی","amenity":"bank"},"name":"بانک کشاورزی","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/صادرات":{"tags":{"name":"صادرات","amenity":"bank"},"name":"صادرات","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ملی":{"tags":{"name":"ملی","amenity":"bank"},"name":"ملی","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/پست بانک":{"tags":{"name":"پست بانک","amenity":"bank"},"name":"پست بانک","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารกรุงเทพ":{"tags":{"name":"ธนาคารกรุงเทพ","amenity":"bank"},"name":"ธนาคารกรุงเทพ","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารกรุงไทย":{"tags":{"name":"ธนาคารกรุงไทย","amenity":"bank"},"name":"ธนาคารกรุงไทย","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารกสิกรไทย":{"tags":{"name":"ธนาคารกสิกรไทย","amenity":"bank"},"name":"ธนาคารกสิกรไทย","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารออมสิน":{"tags":{"name":"ธนาคารออมสิน","amenity":"bank"},"name":"ธนาคารออมสิน","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารไทยพาณิชย์":{"tags":{"name":"ธนาคารไทยพาณิชย์","amenity":"bank"},"name":"ธนาคารไทยพาณิชย์","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/みずほ銀行":{"tags":{"name":"みずほ銀行","amenity":"bank"},"name":"みずほ銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/りそな銀行":{"tags":{"name":"りそな銀行","amenity":"bank"},"name":"りそな銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/三井住友銀行":{"tags":{"name":"三井住友銀行","amenity":"bank"},"name":"三井住友銀行","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国农业银行":{"tags":{"name":"中国农业银行","amenity":"bank"},"name":"中国农业银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国工商银行":{"tags":{"name":"中国工商银行","amenity":"bank"},"name":"中国工商银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国建设银行":{"tags":{"name":"中国建设银行","amenity":"bank"},"name":"中国建设银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国邮政储蓄银行":{"tags":{"name":"中国邮政储蓄银行","amenity":"bank"},"name":"中国邮政储蓄银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国银行":{"tags":{"name":"中国银行","amenity":"bank"},"name":"中国银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/交通银行":{"tags":{"name":"交通银行","amenity":"bank"},"name":"交通银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/京都中央信用金庫":{"tags":{"name":"京都中央信用金庫","amenity":"bank"},"name":"京都中央信用金庫","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/京都銀行":{"tags":{"name":"京都銀行","amenity":"bank"},"name":"京都銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/农业银行":{"tags":{"name":"农业银行","amenity":"bank"},"name":"农业银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/北海道銀行":{"tags":{"name":"北海道銀行","amenity":"bank"},"name":"北海道銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/合作金庫銀行":{"tags":{"name":"合作金庫銀行","amenity":"bank"},"name":"合作金庫銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/土地銀行":{"tags":{"name":"土地銀行","amenity":"bank"},"name":"土地銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/工商银行":{"tags":{"name":"工商银行","amenity":"bank"},"name":"工商银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/建设银行":{"tags":{"name":"建设银行","amenity":"bank"},"name":"建设银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/彰化銀行":{"tags":{"name":"彰化銀行","amenity":"bank"},"name":"彰化銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/招商银行":{"tags":{"name":"招商银行","amenity":"bank"},"name":"招商银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/横浜銀行":{"tags":{"name":"横浜銀行","amenity":"bank"},"name":"横浜銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/第一銀行":{"tags":{"name":"第一銀行","amenity":"bank"},"name":"第一銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/華南銀行":{"tags":{"name":"華南銀行","amenity":"bank"},"name":"華南銀行","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/기업은행":{"tags":{"name":"기업은행","amenity":"bank"},"name":"기업은행","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/농협":{"tags":{"name":"농협","amenity":"bank"},"name":"농협","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/새마을금고":{"tags":{"name":"새마을금고","amenity":"bank"},"name":"새마을금고","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/하나은행":{"tags":{"name":"하나은행","amenity":"bank"},"name":"하나은행","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bar/Bar Centrale":{"tags":{"name":"Bar Centrale","amenity":"bar"},"name":"Bar Centrale","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/bar/Bar Sport":{"tags":{"name":"Bar Sport","amenity":"bar"},"name":"Bar Sport","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/bar/Beach Bar":{"tags":{"name":"Beach Bar","amenity":"bar"},"name":"Beach Bar","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/bar/Pool Bar":{"tags":{"name":"Pool Bar","amenity":"bar"},"name":"Pool Bar","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/bicycle_rental/Bicing":{"tags":{"name":"Bicing","amenity":"bicycle_rental"},"name":"Bicing","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator"],"suggestion":true},"amenity/bicycle_rental/Call a Bike":{"tags":{"name":"Call a Bike","amenity":"bicycle_rental"},"name":"Call a Bike","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator"],"suggestion":true},"amenity/bicycle_rental/Grid":{"tags":{"name":"Grid","amenity":"bicycle_rental"},"name":"Grid","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator"],"suggestion":true},"amenity/bicycle_rental/Mibici":{"tags":{"name":"Mibici","amenity":"bicycle_rental"},"name":"Mibici","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator"],"suggestion":true},"amenity/bicycle_rental/metropolradruhr":{"tags":{"name":"metropolradruhr","amenity":"bicycle_rental"},"name":"metropolradruhr","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator"],"suggestion":true},"amenity/bureau_de_change/Abitab":{"tags":{"name":"Abitab","amenity":"bureau_de_change"},"name":"Abitab","icon":"bank","geometry":["point","vertex"],"fields":["name","operator","currency_multi"],"suggestion":true},"amenity/bureau_de_change/Change":{"tags":{"name":"Change","amenity":"bureau_de_change"},"name":"Change","icon":"bank","geometry":["point","vertex"],"fields":["name","operator","currency_multi"],"suggestion":true},"amenity/bureau_de_change/Travelex":{"tags":{"name":"Travelex","amenity":"bureau_de_change"},"name":"Travelex","icon":"bank","geometry":["point","vertex"],"fields":["name","operator","currency_multi"],"suggestion":true},"amenity/cafe/85度C":{"tags":{"name":"85度C","amenity":"cafe"},"name":"85度C","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Bar Kafe":{"tags":{"name":"Bar Kafe","amenity":"cafe"},"name":"Bar Kafe","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Barista":{"tags":{"name":"Barista","amenity":"cafe"},"name":"Barista","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Bonafide":{"tags":{"name":"Bonafide","amenity":"cafe"},"name":"Bonafide","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafe Coffee Day":{"tags":{"name":"Cafe Coffee Day","amenity":"cafe"},"name":"Cafe Coffee Day","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafe Nero":{"tags":{"name":"Cafe Nero","amenity":"cafe"},"name":"Cafe Nero","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafeteria":{"tags":{"name":"Cafeteria","amenity":"cafe"},"name":"Cafeteria","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafetería":{"tags":{"name":"Cafetería","amenity":"cafe"},"name":"Cafetería","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Caffè Nero":{"tags":{"name":"Caffè Nero","amenity":"cafe"},"name":"Caffè Nero","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café Amazon":{"tags":{"name":"Café Amazon","amenity":"cafe"},"name":"Café Amazon","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café Central":{"tags":{"name":"Café Central","amenity":"cafe"},"name":"Café Central","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café de la Place":{"tags":{"name":"Café de la Place","amenity":"cafe"},"name":"Café de la Place","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café des Sports":{"tags":{"name":"Café des Sports","amenity":"cafe"},"name":"Café des Sports","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Caribou Coffee":{"tags":{"name":"Caribou Coffee","amenity":"cafe"},"name":"Caribou Coffee","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Fellows":{"tags":{"name":"Coffee Fellows","amenity":"cafe"},"name":"Coffee Fellows","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee House":{"tags":{"name":"Coffee House","amenity":"cafe"},"name":"Coffee House","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Island":{"tags":{"name":"Coffee Island","amenity":"cafe"},"name":"Coffee Island","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Shop":{"tags":{"name":"Coffee Shop","amenity":"cafe"},"name":"Coffee Shop","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Time":{"tags":{"name":"Coffee Time","amenity":"cafe"},"name":"Coffee Time","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Costa":{"tags":{"name":"Costa","amenity":"cafe"},"name":"Costa","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Country Style":{"tags":{"name":"Country Style","amenity":"cafe"},"name":"Country Style","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Dunkin' Donuts":{"tags":{"name":"Dunkin' Donuts","cuisine":"donut","amenity":"cafe"},"name":"Dunkin' Donuts","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Eiscafe Dolomiti":{"tags":{"name":"Eiscafe Dolomiti","amenity":"cafe"},"name":"Eiscafe Dolomiti","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Eiscafe Venezia":{"tags":{"name":"Eiscafe Venezia","amenity":"cafe"},"name":"Eiscafe Venezia","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Espresso House":{"tags":{"name":"Espresso House","amenity":"cafe"},"name":"Espresso House","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Havanna":{"tags":{"name":"Havanna","amenity":"cafe"},"name":"Havanna","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Internet Cafe":{"tags":{"name":"Internet Cafe","amenity":"cafe"},"name":"Internet Cafe","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Kafe":{"tags":{"name":"Kafe","amenity":"cafe"},"name":"Kafe","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Krispy Kreme":{"tags":{"name":"Krispy Kreme","amenity":"cafe"},"name":"Krispy Kreme","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Le Pain Quotidien":{"tags":{"name":"Le Pain Quotidien","amenity":"cafe"},"name":"Le Pain Quotidien","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/McCafé":{"tags":{"name":"McCafé","amenity":"cafe","cuisine":"coffee_shop"},"name":"McCafé","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Peet's Coffee & Tea":{"tags":{"name":"Peet's Coffee & Tea","amenity":"cafe"},"name":"Peet's Coffee & Tea","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Pret A Manger":{"tags":{"name":"Pret A Manger","amenity":"cafe"},"name":"Pret A Manger","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Prime":{"tags":{"name":"Prime","amenity":"cafe"},"name":"Prime","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Second Cup":{"tags":{"name":"Second Cup","amenity":"cafe"},"name":"Second Cup","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Segafredo":{"tags":{"name":"Segafredo","amenity":"cafe"},"name":"Segafredo","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Starbucks":{"tags":{"name":"Starbucks","cuisine":"coffee_shop","amenity":"cafe"},"name":"Starbucks","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/The Coffee Bean & Tea Leaf":{"tags":{"name":"The Coffee Bean & Tea Leaf","amenity":"cafe"},"name":"The Coffee Bean & Tea Leaf","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/The Coffee Club":{"tags":{"name":"The Coffee Club","amenity":"cafe"},"name":"The Coffee Club","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Tim Hortons":{"tags":{"name":"Tim Hortons","amenity":"cafe"},"name":"Tim Hortons","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Traveler's Coffee":{"tags":{"name":"Traveler's Coffee","amenity":"cafe"},"name":"Traveler's Coffee","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Wayne's Coffee":{"tags":{"name":"Wayne's Coffee","amenity":"cafe"},"name":"Wayne's Coffee","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Бистро":{"tags":{"name":"Бистро","amenity":"cafe"},"name":"Бистро","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Буфет":{"tags":{"name":"Буфет","amenity":"cafe"},"name":"Буфет","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Встреча":{"tags":{"name":"Встреча","amenity":"cafe"},"name":"Встреча","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Даблби":{"tags":{"name":"Даблби","amenity":"cafe"},"name":"Даблби","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Закусочная":{"tags":{"name":"Закусочная","amenity":"cafe"},"name":"Закусочная","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Кофе Хауз":{"tags":{"name":"Кофе Хауз","amenity":"cafe"},"name":"Кофе Хауз","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Кофейня":{"tags":{"name":"Кофейня","amenity":"cafe"},"name":"Кофейня","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Лакомка":{"tags":{"name":"Лакомка","amenity":"cafe"},"name":"Лакомка","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Летнее кафе":{"tags":{"name":"Летнее кафе","amenity":"cafe"},"name":"Летнее кафе","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Пельменная":{"tags":{"name":"Пельменная","amenity":"cafe"},"name":"Пельменная","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Пиццерия":{"tags":{"name":"Пиццерия","amenity":"cafe"},"name":"Пиццерия","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Рандеву":{"tags":{"name":"Рандеву","amenity":"cafe"},"name":"Рандеву","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Сказка":{"tags":{"name":"Сказка","amenity":"cafe"},"name":"Сказка","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Старбакс":{"tags":{"name":"Старбакс","amenity":"cafe"},"name":"Старбакс","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Столовая":{"tags":{"name":"Столовая","amenity":"cafe"},"name":"Столовая","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Уют":{"tags":{"name":"Уют","amenity":"cafe"},"name":"Уют","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Хуторок":{"tags":{"name":"Хуторок","amenity":"cafe"},"name":"Хуторок","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Шашлычная":{"tags":{"name":"Шашлычная","amenity":"cafe"},"name":"Шашлычная","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Шоколад":{"tags":{"name":"Шоколад","amenity":"cafe"},"name":"Шоколад","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Шоколадница":{"tags":{"name":"Шоколадница","amenity":"cafe"},"name":"Шоколадница","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/ארומה":{"tags":{"name":"ארומה","amenity":"cafe"},"name":"ארומה","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/مقهى":{"tags":{"name":"مقهى","amenity":"cafe"},"name":"مقهى","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/คาเฟ่ อเมซอน":{"tags":{"name":"คาเฟ่ อเมซอน","amenity":"cafe"},"name":"คาเฟ่ อเมซอน","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/エクセルシオール カフェ":{"tags":{"name":"エクセルシオール カフェ","amenity":"cafe"},"name":"エクセルシオール カフェ","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/カフェ・ド・クリエ":{"tags":{"name":"カフェ・ド・クリエ","name:en":"Cafe de CRIE","amenity":"cafe"},"name":"カフェ・ド・クリエ","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/カフェ・ベローチェ":{"tags":{"name":"カフェ・ベローチェ","amenity":"cafe"},"name":"カフェ・ベローチェ","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/コメダ珈琲店":{"tags":{"name":"コメダ珈琲店","amenity":"cafe"},"name":"コメダ珈琲店","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/サンマルクカフェ":{"tags":{"name":"サンマルクカフェ","amenity":"cafe"},"name":"サンマルクカフェ","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/スターバックス":{"tags":{"name":"スターバックス","name:en":"Starbucks","amenity":"cafe"},"name":"スターバックス","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/タリーズコーヒー":{"tags":{"name":"タリーズコーヒー","amenity":"cafe"},"name":"タリーズコーヒー","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/ドトールコーヒーショップ":{"tags":{"name":"ドトールコーヒーショップ","amenity":"cafe"},"name":"ドトールコーヒーショップ","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/星巴克":{"tags":{"name":"星巴克","amenity":"cafe"},"name":"星巴克","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/스타벅스":{"tags":{"name":"스타벅스","amenity":"cafe"},"name":"스타벅스","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/car_rental/Alamo":{"tags":{"name":"Alamo","amenity":"car_rental"},"name":"Alamo","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Avis":{"tags":{"name":"Avis","amenity":"car_rental"},"name":"Avis","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Budget":{"tags":{"name":"Budget","amenity":"car_rental"},"name":"Budget","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Enterprise":{"tags":{"name":"Enterprise","amenity":"car_rental"},"name":"Enterprise","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Enterprise Rent-a-Car":{"tags":{"name":"Enterprise Rent-a-Car","amenity":"car_rental"},"name":"Enterprise Rent-a-Car","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Europcar":{"tags":{"name":"Europcar","amenity":"car_rental"},"name":"Europcar","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Hertz":{"tags":{"name":"Hertz","amenity":"car_rental"},"name":"Hertz","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Localiza":{"tags":{"name":"Localiza","amenity":"car_rental"},"name":"Localiza","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Sixt":{"tags":{"name":"Sixt","amenity":"car_rental"},"name":"Sixt","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/Thrifty":{"tags":{"name":"Thrifty","amenity":"car_rental"},"name":"Thrifty","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/U-Haul":{"tags":{"name":"U-Haul","amenity":"car_rental"},"name":"U-Haul","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/オリックスレンタカー":{"tags":{"name":"オリックスレンタカー","amenity":"car_rental"},"name":"オリックスレンタカー","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/トヨタレンタカー":{"tags":{"name":"トヨタレンタカー","amenity":"car_rental"},"name":"トヨタレンタカー","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/トヨタレンタリース":{"tags":{"name":"トヨタレンタリース","amenity":"car_rental"},"name":"トヨタレンタリース","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_rental/ニッポンレンタカー":{"tags":{"name":"ニッポンレンタカー","amenity":"car_rental"},"name":"ニッポンレンタカー","icon":"car","geometry":["point","area"],"fields":["name","operator"],"suggestion":true},"amenity/car_wash/Autolavaggio":{"tags":{"name":"Autolavaggio","amenity":"car_wash"},"name":"Autolavaggio","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/H-E-B Car Wash":{"tags":{"name":"H-E-B Car Wash","amenity":"car_wash"},"name":"H-E-B Car Wash","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Lavage Auto":{"tags":{"name":"Lavage Auto","amenity":"car_wash"},"name":"Lavage Auto","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Lavazh":{"tags":{"name":"Lavazh","amenity":"car_wash"},"name":"Lavazh","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Myjnia":{"tags":{"name":"Myjnia","amenity":"car_wash"},"name":"Myjnia","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Myjnia bezdotykowa":{"tags":{"name":"Myjnia bezdotykowa","amenity":"car_wash"},"name":"Myjnia bezdotykowa","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Myjnia samochodowa":{"tags":{"name":"Myjnia samochodowa","amenity":"car_wash"},"name":"Myjnia samochodowa","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Spălătorie Auto":{"tags":{"name":"Spălătorie Auto","amenity":"car_wash"},"name":"Spălătorie Auto","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Spălătorie auto":{"tags":{"name":"Spălătorie auto","amenity":"car_wash"},"name":"Spălătorie auto","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/car_wash/Автомийка":{"tags":{"name":"Автомийка","amenity":"car_wash"},"name":"Автомийка","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours"],"suggestion":true},"amenity/cinema/Cinema City":{"tags":{"name":"Cinema City","amenity":"cinema"},"name":"Cinema City","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/cinema/Cinemark":{"tags":{"name":"Cinemark","amenity":"cinema"},"name":"Cinemark","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/cinema/Cinemex":{"tags":{"name":"Cinemex","amenity":"cinema"},"name":"Cinemex","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/cinema/Cinepolis":{"tags":{"name":"Cinepolis","amenity":"cinema"},"name":"Cinepolis","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/cinema/Cineworld":{"tags":{"name":"Cineworld","amenity":"cinema"},"name":"Cineworld","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/cinema/Odeon":{"tags":{"name":"Odeon","amenity":"cinema"},"name":"Odeon","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/clinic/ФАП":{"tags":{"name":"ФАП","amenity":"clinic"},"name":"ФАП","icon":"hospital","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Aspen Dental":{"tags":{"name":"Aspen Dental","amenity":"dentist"},"name":"Aspen Dental","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Consultorio Dental":{"tags":{"name":"Consultorio Dental","amenity":"dentist"},"name":"Consultorio Dental","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Dentista":{"tags":{"name":"Dentista","amenity":"dentist"},"name":"Dentista","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Family Dentistry":{"tags":{"name":"Family Dentistry","amenity":"dentist"},"name":"Family Dentistry","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Vitaldent":{"tags":{"name":"Vitaldent","amenity":"dentist"},"name":"Vitaldent","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Стоматолог":{"tags":{"name":"Стоматолог","amenity":"dentist"},"name":"Стоматолог","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Стоматологія":{"tags":{"name":"Стоматологія","amenity":"dentist"},"name":"Стоматологія","icon":"dentist","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/doctors/Háziorvosi rendelő":{"tags":{"name":"Háziorvosi rendelő","amenity":"doctors"},"name":"Háziorvosi rendelő","icon":"hospital","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/doctors/Инвитро":{"tags":{"name":"Инвитро","amenity":"doctors"},"name":"Инвитро","icon":"hospital","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/driving_school/Автодром":{"tags":{"name":"Автодром","amenity":"driving_school"},"name":"Автодром","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"amenity/fast_food/A&W":{"tags":{"name":"A&W","amenity":"fast_food"},"name":"A&W","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Ali Baba":{"tags":{"name":"Ali Baba","amenity":"fast_food"},"name":"Ali Baba","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Angel's Burger":{"tags":{"name":"Angel's Burger","amenity":"fast_food"},"name":"Angel's Burger","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Antalya":{"tags":{"name":"Antalya","amenity":"fast_food"},"name":"Antalya","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Arby's":{"tags":{"name":"Arby's","amenity":"fast_food"},"name":"Arby's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Asia Bistro":{"tags":{"name":"Asia Bistro","amenity":"fast_food"},"name":"Asia Bistro","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Asia Wok":{"tags":{"name":"Asia Wok","amenity":"fast_food"},"name":"Asia Wok","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Baskin-Robbins":{"tags":{"name":"Baskin-Robbins","amenity":"fast_food"},"name":"Baskin-Robbins","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Bistro":{"tags":{"name":"Bistro","amenity":"fast_food"},"name":"Bistro","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Bob's":{"tags":{"name":"Bob's","amenity":"fast_food"},"name":"Bob's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Bojangles":{"tags":{"name":"Bojangles","amenity":"fast_food"},"name":"Bojangles","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Booster Juice":{"tags":{"name":"Booster Juice","amenity":"fast_food"},"name":"Booster Juice","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Boston Market":{"tags":{"name":"Boston Market","amenity":"fast_food"},"name":"Boston Market","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Braum's":{"tags":{"name":"Braum's","amenity":"fast_food"},"name":"Braum's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Burger Machine":{"tags":{"name":"Burger Machine","amenity":"fast_food"},"name":"Burger Machine","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Büfé":{"tags":{"name":"Büfé","amenity":"fast_food"},"name":"Büfé","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Captain D's":{"tags":{"name":"Captain D's","amenity":"fast_food"},"name":"Captain D's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chicken Express":{"tags":{"name":"Chicken Express","amenity":"fast_food"},"name":"Chicken Express","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chipotle":{"tags":{"name":"Chipotle","cuisine":"mexican","amenity":"fast_food"},"name":"Chipotle","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chowking":{"tags":{"name":"Chowking","amenity":"fast_food"},"name":"Chowking","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/CoCo壱番屋":{"tags":{"name":"CoCo壱番屋","amenity":"fast_food"},"name":"CoCo壱番屋","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Cold Stone Creamery":{"tags":{"name":"Cold Stone Creamery","amenity":"fast_food"},"name":"Cold Stone Creamery","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Cook Out":{"tags":{"name":"Cook Out","amenity":"fast_food"},"name":"Cook Out","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Culver's":{"tags":{"name":"Culver's","amenity":"fast_food"},"name":"Culver's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/DQ":{"tags":{"name":"DQ","amenity":"fast_food"},"name":"DQ","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Dairy Queen":{"tags":{"name":"Dairy Queen","amenity":"fast_food"},"name":"Dairy Queen","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Del Taco":{"tags":{"name":"Del Taco","amenity":"fast_food"},"name":"Del Taco","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Everest":{"tags":{"name":"Everest","amenity":"fast_food"},"name":"Everest","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Extreme Pita":{"tags":{"name":"Extreme Pita","amenity":"fast_food"},"name":"Extreme Pita","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Fazoli's":{"tags":{"name":"Fazoli's","amenity":"fast_food"},"name":"Fazoli's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Firehouse Subs":{"tags":{"name":"Firehouse Subs","amenity":"fast_food"},"name":"Firehouse Subs","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Fish & Chips":{"tags":{"name":"Fish & Chips","amenity":"fast_food"},"name":"Fish & Chips","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Fish and Chips":{"tags":{"name":"Fish and Chips","amenity":"fast_food"},"name":"Fish and Chips","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Five Guys":{"tags":{"name":"Five Guys","amenity":"fast_food"},"name":"Five Guys","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Food Court":{"tags":{"name":"Food Court","amenity":"fast_food"},"name":"Food Court","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Greenwich":{"tags":{"name":"Greenwich","amenity":"fast_food"},"name":"Greenwich","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Habib's":{"tags":{"name":"Habib's","amenity":"fast_food"},"name":"Habib's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Hallo Pizza":{"tags":{"name":"Hallo Pizza","amenity":"fast_food"},"name":"Hallo Pizza","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Harvey's":{"tags":{"name":"Harvey's","amenity":"fast_food"},"name":"Harvey's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Hesburger":{"tags":{"name":"Hesburger","amenity":"fast_food"},"name":"Hesburger","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Istanbul":{"tags":{"name":"Istanbul","amenity":"fast_food"},"name":"Istanbul","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Istanbul Kebab":{"tags":{"name":"Istanbul Kebab","amenity":"fast_food"},"name":"Istanbul Kebab","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jamba Juice":{"tags":{"name":"Jamba Juice","amenity":"fast_food"},"name":"Jamba Juice","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jersey Mike's Subs":{"tags":{"name":"Jersey Mike's Subs","amenity":"fast_food"},"name":"Jersey Mike's Subs","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jimmy John's":{"tags":{"name":"Jimmy John's","cuisine":"sandwich","amenity":"fast_food"},"name":"Jimmy John's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jollibee":{"tags":{"name":"Jollibee","amenity":"fast_food"},"name":"Jollibee","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/KFC":{"tags":{"name":"KFC","cuisine":"chicken","amenity":"fast_food"},"name":"KFC","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/KFC/Taco Bell":{"tags":{"name":"KFC/Taco Bell","amenity":"fast_food"},"name":"KFC/Taco Bell","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kebab House":{"tags":{"name":"Kebab House","amenity":"fast_food"},"name":"Kebab House","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kebabai":{"tags":{"name":"Kebabai","amenity":"fast_food"},"name":"Kebabai","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kochlöffel":{"tags":{"name":"Kochlöffel","amenity":"fast_food"},"name":"Kochlöffel","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kotipizza":{"tags":{"name":"Kotipizza","amenity":"fast_food"},"name":"Kotipizza","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Krystal":{"tags":{"name":"Krystal","amenity":"fast_food"},"name":"Krystal","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Little Caesars":{"tags":{"name":"Little Caesars","amenity":"fast_food"},"name":"Little Caesars","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Little Caesars Pizza":{"tags":{"name":"Little Caesars Pizza","amenity":"fast_food"},"name":"Little Caesars Pizza","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Lotteria":{"tags":{"name":"Lotteria","amenity":"fast_food"},"name":"Lotteria","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Max":{"tags":{"name":"Max","amenity":"fast_food"},"name":"Max","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Minute Burger":{"tags":{"name":"Minute Burger","amenity":"fast_food"},"name":"Minute Burger","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Mr. Sub":{"tags":{"name":"Mr. Sub","amenity":"fast_food"},"name":"Mr. Sub","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/New York Pizza":{"tags":{"name":"New York Pizza","amenity":"fast_food"},"name":"New York Pizza","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Nordsee":{"tags":{"name":"Nordsee","amenity":"fast_food"},"name":"Nordsee","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Papa Murphy's":{"tags":{"name":"Papa Murphy's","amenity":"fast_food"},"name":"Papa Murphy's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pinulito":{"tags":{"name":"Pinulito","amenity":"fast_food"},"name":"Pinulito","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pita Pit":{"tags":{"name":"Pita Pit","amenity":"fast_food"},"name":"Pita Pit","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza Hut Delivery":{"tags":{"name":"Pizza Hut Delivery","amenity":"fast_food"},"name":"Pizza Hut Delivery","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza King":{"tags":{"name":"Pizza King","amenity":"fast_food"},"name":"Pizza King","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza Nova":{"tags":{"name":"Pizza Nova","amenity":"fast_food"},"name":"Pizza Nova","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza Pizza":{"tags":{"name":"Pizza Pizza","amenity":"fast_food"},"name":"Pizza Pizza","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pollo Campero":{"tags":{"name":"Pollo Campero","amenity":"fast_food"},"name":"Pollo Campero","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pollo Granjero":{"tags":{"name":"Pollo Granjero","amenity":"fast_food"},"name":"Pollo Granjero","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Popeyes Louisiana Kitchen":{"tags":{"name":"Popeyes Louisiana Kitchen","amenity":"fast_food"},"name":"Popeyes Louisiana Kitchen","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Qdoba":{"tags":{"name":"Qdoba","amenity":"fast_food"},"name":"Qdoba","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Quick":{"tags":{"name":"Quick","amenity":"fast_food"},"name":"Quick","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Quiznos":{"tags":{"name":"Quiznos","amenity":"fast_food"},"name":"Quiznos","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Rally's":{"tags":{"name":"Rally's","amenity":"fast_food"},"name":"Rally's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Red Rooster":{"tags":{"name":"Red Rooster","amenity":"fast_food"},"name":"Red Rooster","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Sbarro":{"tags":{"name":"Sbarro","amenity":"fast_food"},"name":"Sbarro","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Schlotzsky's Deli":{"tags":{"name":"Schlotzsky's Deli","amenity":"fast_food"},"name":"Schlotzsky's Deli","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Sibylla":{"tags":{"name":"Sibylla","amenity":"fast_food"},"name":"Sibylla","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Sonic":{"tags":{"name":"Sonic","cuisine":"burger","amenity":"fast_food"},"name":"Sonic","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Steers":{"tags":{"name":"Steers","amenity":"fast_food"},"name":"Steers","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Subway":{"tags":{"name":"Subway","amenity":"fast_food"},"name":"Subway","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Bueno":{"tags":{"name":"Taco Bueno","amenity":"fast_food"},"name":"Taco Bueno","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Cabana":{"tags":{"name":"Taco Cabana","amenity":"fast_food"},"name":"Taco Cabana","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Del Mar":{"tags":{"name":"Taco Del Mar","amenity":"fast_food"},"name":"Taco Del Mar","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Time":{"tags":{"name":"Taco Time","amenity":"fast_food"},"name":"Taco Time","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Telepizza":{"tags":{"name":"Telepizza","amenity":"fast_food"},"name":"Telepizza","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Thai Express":{"tags":{"name":"Thai Express","amenity":"fast_food"},"name":"Thai Express","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/The Pizza Company":{"tags":{"name":"The Pizza Company","amenity":"fast_food"},"name":"The Pizza Company","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Whataburger":{"tags":{"name":"Whataburger","amenity":"fast_food"},"name":"Whataburger","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/White Castle":{"tags":{"name":"White Castle","amenity":"fast_food"},"name":"White Castle","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Wienerschnitzel":{"tags":{"name":"Wienerschnitzel","amenity":"fast_food"},"name":"Wienerschnitzel","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Wimpy":{"tags":{"name":"Wimpy","amenity":"fast_food"},"name":"Wimpy","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Zaxby's":{"tags":{"name":"Zaxby's","amenity":"fast_food"},"name":"Zaxby's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Γρηγόρης":{"tags":{"name":"Γρηγόρης","amenity":"fast_food"},"name":"Γρηγόρης","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Бургер Кинг":{"tags":{"name":"Бургер Кинг","amenity":"fast_food"},"name":"Бургер Кинг","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Крошка Картошка":{"tags":{"name":"Крошка Картошка","amenity":"fast_food"},"name":"Крошка Картошка","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Макдоналдс":{"tags":{"name":"Макдоналдс","name:en":"McDonald's","amenity":"fast_food"},"name":"Макдоналдс","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Робин Сдобин":{"tags":{"name":"Робин Сдобин","amenity":"fast_food"},"name":"Робин Сдобин","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Русский Аппетит":{"tags":{"name":"Русский Аппетит","amenity":"fast_food"},"name":"Русский Аппетит","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Сабвэй":{"tags":{"name":"Сабвэй","amenity":"fast_food"},"name":"Сабвэй","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Стардог!s":{"tags":{"name":"Стардог!s","amenity":"fast_food"},"name":"Стардог!s","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Теремок":{"tags":{"name":"Теремок","amenity":"fast_food"},"name":"Теремок","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Шаверма":{"tags":{"name":"Шаверма","amenity":"fast_food"},"name":"Шаверма","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Шаурма":{"tags":{"name":"Шаурма","amenity":"fast_food"},"name":"Шаурма","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/かっぱ寿司":{"tags":{"name":"かっぱ寿司","amenity":"fast_food"},"name":"かっぱ寿司","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/かつや":{"tags":{"name":"かつや","amenity":"fast_food"},"name":"かつや","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/くら寿司":{"tags":{"name":"くら寿司","amenity":"fast_food"},"name":"くら寿司","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/すき家":{"tags":{"name":"すき家","name:en":"SUKIYA","amenity":"fast_food"},"name":"すき家","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/なか卯":{"tags":{"name":"なか卯","amenity":"fast_food"},"name":"なか卯","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ほっかほっか亭":{"tags":{"name":"ほっかほっか亭","amenity":"fast_food"},"name":"ほっかほっか亭","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ほっともっと":{"tags":{"name":"ほっともっと","amenity":"fast_food"},"name":"ほっともっと","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/オリジン弁当":{"tags":{"name":"オリジン弁当","amenity":"fast_food"},"name":"オリジン弁当","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ケンタッキーフライドチキン":{"tags":{"name":"ケンタッキーフライドチキン","cuisine":"chicken","name:en":"KFC","amenity":"fast_food"},"name":"ケンタッキーフライドチキン","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/サブウェイ":{"tags":{"name":"サブウェイ","amenity":"fast_food"},"name":"サブウェイ","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/スシロー":{"tags":{"name":"スシロー","amenity":"fast_food"},"name":"スシロー","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/マクドナルド":{"tags":{"name":"マクドナルド","cuisine":"burger","name:en":"McDonald's","amenity":"fast_food"},"name":"マクドナルド","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ミスタードーナツ":{"tags":{"name":"ミスタードーナツ","amenity":"fast_food"},"name":"ミスタードーナツ","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/モスバーガー":{"tags":{"name":"モスバーガー","name:en":"MOS BURGER","amenity":"fast_food"},"name":"モスバーガー","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ロッテリア":{"tags":{"name":"ロッテリア","amenity":"fast_food"},"name":"ロッテリア","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/吉野家":{"tags":{"name":"吉野家","amenity":"fast_food"},"name":"吉野家","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/幸楽苑":{"tags":{"name":"幸楽苑","amenity":"fast_food"},"name":"幸楽苑","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/摩斯漢堡":{"tags":{"name":"摩斯漢堡","amenity":"fast_food"},"name":"摩斯漢堡","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/松屋":{"tags":{"name":"松屋","name:en":"Matsuya","amenity":"fast_food"},"name":"松屋","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/肯德基":{"tags":{"name":"肯德基","amenity":"fast_food"},"name":"肯德基","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/麥當勞":{"tags":{"name":"麥當勞","amenity":"fast_food"},"name":"麥當勞","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/麦当劳":{"tags":{"name":"麦当劳","amenity":"fast_food"},"name":"麦当劳","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/롯데리아":{"tags":{"name":"롯데리아","amenity":"fast_food"},"name":"롯데리아","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fuel/76":{"tags":{"name":"76","amenity":"fuel"},"name":"76","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ADNOC":{"tags":{"name":"ADNOC","amenity":"fuel"},"name":"ADNOC","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ANP":{"tags":{"name":"ANP","amenity":"fuel"},"name":"ANP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ARAL":{"tags":{"name":"ARAL","amenity":"fuel"},"name":"ARAL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Aegean":{"tags":{"name":"Aegean","amenity":"fuel"},"name":"Aegean","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Afriquia":{"tags":{"name":"Afriquia","amenity":"fuel"},"name":"Afriquia","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Agip":{"tags":{"name":"Agip","amenity":"fuel"},"name":"Agip","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Agrola":{"tags":{"name":"Agrola","amenity":"fuel"},"name":"Agrola","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Alon":{"tags":{"name":"Alon","amenity":"fuel"},"name":"Alon","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Alpet":{"tags":{"name":"Alpet","amenity":"fuel"},"name":"Alpet","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Api":{"tags":{"name":"Api","amenity":"fuel"},"name":"Api","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Aral":{"tags":{"name":"Aral","amenity":"fuel"},"name":"Aral","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Arco":{"tags":{"name":"Arco","amenity":"fuel"},"name":"Arco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Avanti":{"tags":{"name":"Avanti","amenity":"fuel"},"name":"Avanti","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Avia":{"tags":{"name":"Avia","amenity":"fuel"},"name":"Avia","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BEBECO":{"tags":{"name":"BEBECO","amenity":"fuel"},"name":"BEBECO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BFT":{"tags":{"name":"BFT","amenity":"fuel"},"name":"BFT","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BHPetrol":{"tags":{"name":"BHPetrol","amenity":"fuel"},"name":"BHPetrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BP":{"tags":{"name":"BP","amenity":"fuel"},"name":"BP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BR":{"tags":{"name":"BR","amenity":"fuel"},"name":"BR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Bangchak":{"tags":{"name":"Bangchak","amenity":"fuel"},"name":"Bangchak","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Benzina":{"tags":{"name":"Benzina","amenity":"fuel"},"name":"Benzina","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Bliska":{"tags":{"name":"Bliska","amenity":"fuel"},"name":"Bliska","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CAMPSA":{"tags":{"name":"CAMPSA","amenity":"fuel"},"name":"CAMPSA","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CARREFOUR":{"tags":{"name":"CARREFOUR","amenity":"fuel"},"name":"CARREFOUR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CEPSA":{"tags":{"name":"CEPSA","amenity":"fuel"},"name":"CEPSA","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CNG":{"tags":{"name":"CNG","amenity":"fuel"},"name":"CNG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Caltex":{"tags":{"name":"Caltex","amenity":"fuel"},"name":"Caltex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Campsa":{"tags":{"name":"Campsa","amenity":"fuel"},"name":"Campsa","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cenex":{"tags":{"name":"Cenex","amenity":"fuel"},"name":"Cenex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cepsa":{"tags":{"name":"Cepsa","amenity":"fuel"},"name":"Cepsa","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ceypetco":{"tags":{"name":"Ceypetco","amenity":"fuel"},"name":"Ceypetco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Chevron":{"tags":{"name":"Chevron","amenity":"fuel"},"name":"Chevron","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Citgo":{"tags":{"name":"Citgo","amenity":"fuel"},"name":"Citgo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Clark":{"tags":{"name":"Clark","amenity":"fuel"},"name":"Clark","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Conoco":{"tags":{"name":"Conoco","amenity":"fuel"},"name":"Conoco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Copec":{"tags":{"name":"Copec","amenity":"fuel"},"name":"Copec","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Copetrol":{"tags":{"name":"Copetrol","amenity":"fuel"},"name":"Copetrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cosmo":{"tags":{"name":"Cosmo","amenity":"fuel"},"name":"Cosmo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Costco Gas":{"tags":{"name":"Costco Gas","amenity":"fuel"},"name":"Costco Gas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Costco Gasoline":{"tags":{"name":"Costco Gasoline","amenity":"fuel"},"name":"Costco Gasoline","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Crodux":{"tags":{"name":"Crodux","amenity":"fuel"},"name":"Crodux","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Delta":{"tags":{"name":"Delta","amenity":"fuel"},"name":"Delta","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Diamond Shamrock":{"tags":{"name":"Diamond Shamrock","amenity":"fuel"},"name":"Diamond Shamrock","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Drummed Fuel":{"tags":{"name":"Drummed Fuel","amenity":"fuel"},"name":"Drummed Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/EKO":{"tags":{"name":"EKO","amenity":"fuel"},"name":"EKO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ENEOS":{"tags":{"name":"ENEOS","amenity":"fuel"},"name":"ENEOS","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ENI":{"tags":{"name":"ENI","amenity":"fuel"},"name":"ENI","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ERG":{"tags":{"name":"ERG","amenity":"fuel"},"name":"ERG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Elan":{"tags":{"name":"Elan","amenity":"fuel"},"name":"Elan","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eneos":{"tags":{"name":"Eneos","amenity":"fuel"},"name":"Eneos","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Engen":{"tags":{"name":"Engen","amenity":"fuel"},"name":"Engen","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eni":{"tags":{"name":"Eni","amenity":"fuel"},"name":"Eni","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Erg":{"tags":{"name":"Erg","amenity":"fuel"},"name":"Erg","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Esso":{"tags":{"name":"Esso","amenity":"fuel"},"name":"Esso","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/EuroOil":{"tags":{"name":"EuroOil","amenity":"fuel"},"name":"EuroOil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Exxon":{"tags":{"name":"Exxon","amenity":"fuel"},"name":"Exxon","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/F24":{"tags":{"name":"F24","amenity":"fuel"},"name":"F24","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Firezone":{"tags":{"name":"Firezone","amenity":"fuel"},"name":"Firezone","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/GALP":{"tags":{"name":"GALP","amenity":"fuel"},"name":"GALP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/GNV":{"tags":{"name":"GNV","amenity":"fuel"},"name":"GNV","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Gas":{"tags":{"name":"Gas","amenity":"fuel"},"name":"Gas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Gazprom":{"tags":{"name":"Gazprom","amenity":"fuel"},"name":"Gazprom","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/GetGo":{"tags":{"name":"GetGo","amenity":"fuel"},"name":"GetGo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Goil":{"tags":{"name":"Goil","amenity":"fuel"},"name":"Goil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Gulf":{"tags":{"name":"Gulf","amenity":"fuel"},"name":"Gulf","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/H-E-B Fuel":{"tags":{"name":"H-E-B Fuel","amenity":"fuel"},"name":"H-E-B Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/H-E-B Gas":{"tags":{"name":"H-E-B Gas","amenity":"fuel"},"name":"H-E-B Gas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HEM":{"tags":{"name":"HEM","amenity":"fuel"},"name":"HEM","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HP":{"tags":{"name":"HP","amenity":"fuel"},"name":"HP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HP Petrol Pump":{"tags":{"name":"HP Petrol Pump","amenity":"fuel"},"name":"HP Petrol Pump","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Helios":{"tags":{"name":"Helios","amenity":"fuel"},"name":"Helios","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Hess":{"tags":{"name":"Hess","amenity":"fuel"},"name":"Hess","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Hindustan Petroleum":{"tags":{"name":"Hindustan Petroleum","amenity":"fuel"},"name":"Hindustan Petroleum","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Holiday":{"tags":{"name":"Holiday","amenity":"fuel"},"name":"Holiday","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Husky":{"tags":{"name":"Husky","amenity":"fuel"},"name":"Husky","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IES":{"tags":{"name":"IES","amenity":"fuel"},"name":"IES","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IP":{"tags":{"name":"IP","amenity":"fuel"},"name":"IP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Independent Fuel Station":{"tags":{"name":"Independent Fuel Station","amenity":"fuel"},"name":"Independent Fuel Station","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Indipend.":{"tags":{"name":"Indipend.","amenity":"fuel"},"name":"Indipend.","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ingo":{"tags":{"name":"Ingo","amenity":"fuel"},"name":"Ingo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ipiranga":{"tags":{"name":"Ipiranga","amenity":"fuel"},"name":"Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Irving":{"tags":{"name":"Irving","amenity":"fuel"},"name":"Irving","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/JA-SS":{"tags":{"name":"JA-SS","amenity":"fuel"},"name":"JA-SS","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/JOMO":{"tags":{"name":"JOMO","amenity":"fuel"},"name":"JOMO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Jet":{"tags":{"name":"Jet","amenity":"fuel"},"name":"Jet","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Jetti":{"tags":{"name":"Jetti","amenity":"fuel"},"name":"Jetti","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kangaroo":{"tags":{"name":"Kangaroo","amenity":"fuel"},"name":"Kangaroo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kobil":{"tags":{"name":"Kobil","amenity":"fuel"},"name":"Kobil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kroger Fuel":{"tags":{"name":"Kroger Fuel","amenity":"fuel"},"name":"Kroger Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/LPG":{"tags":{"name":"LPG","amenity":"fuel"},"name":"LPG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/LPG Station":{"tags":{"name":"LPG Station","amenity":"fuel"},"name":"LPG Station","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/LUKOIL":{"tags":{"name":"LUKOIL","amenity":"fuel"},"name":"LUKOIL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Liberty":{"tags":{"name":"Liberty","amenity":"fuel"},"name":"Liberty","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lotos":{"tags":{"name":"Lotos","amenity":"fuel"},"name":"Lotos","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lotos Optima":{"tags":{"name":"Lotos Optima","amenity":"fuel"},"name":"Lotos Optima","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Love's":{"tags":{"name":"Love's","amenity":"fuel"},"name":"Love's","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lukoil":{"tags":{"name":"Lukoil","amenity":"fuel"},"name":"Lukoil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MEROIL":{"tags":{"name":"MEROIL","amenity":"fuel"},"name":"MEROIL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MOL":{"tags":{"name":"MOL","amenity":"fuel"},"name":"MOL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MRS":{"tags":{"name":"MRS","amenity":"fuel"},"name":"MRS","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Marathon":{"tags":{"name":"Marathon","amenity":"fuel"},"name":"Marathon","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Maverik":{"tags":{"name":"Maverik","amenity":"fuel"},"name":"Maverik","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Maxol":{"tags":{"name":"Maxol","amenity":"fuel"},"name":"Maxol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Metano":{"tags":{"name":"Metano","amenity":"fuel"},"name":"Metano","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Migrol":{"tags":{"name":"Migrol","amenity":"fuel"},"name":"Migrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Minipump":{"tags":{"name":"Minipump","amenity":"fuel"},"name":"Minipump","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mobil":{"tags":{"name":"Mobil","amenity":"fuel"},"name":"Mobil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mobile":{"tags":{"name":"Mobile","amenity":"fuel"},"name":"Mobile","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mol":{"tags":{"name":"Mol","amenity":"fuel"},"name":"Mol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Moya":{"tags":{"name":"Moya","amenity":"fuel"},"name":"Moya","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Neste":{"tags":{"name":"Neste","amenity":"fuel"},"name":"Neste","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OIL!":{"tags":{"name":"OIL!","amenity":"fuel"},"name":"OIL!","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OK":{"tags":{"name":"OK","amenity":"fuel"},"name":"OK","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OKQ8":{"tags":{"name":"OKQ8","amenity":"fuel"},"name":"OKQ8","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OMV":{"tags":{"name":"OMV","amenity":"fuel"},"name":"OMV","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Oilibya":{"tags":{"name":"Oilibya","amenity":"fuel"},"name":"Oilibya","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Opet":{"tags":{"name":"Opet","amenity":"fuel"},"name":"Opet","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Orlen":{"tags":{"name":"Orlen","amenity":"fuel"},"name":"Orlen","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PETRONOR":{"tags":{"name":"PETRONOR","amenity":"fuel"},"name":"PETRONOR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PSO":{"tags":{"name":"PSO","amenity":"fuel"},"name":"PSO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PSO Petrol Pump":{"tags":{"name":"PSO Petrol Pump","amenity":"fuel"},"name":"PSO Petrol Pump","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PT":{"tags":{"name":"PT","amenity":"fuel"},"name":"PT","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PTT":{"tags":{"name":"PTT","amenity":"fuel"},"name":"PTT","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PV Oil":{"tags":{"name":"PV Oil","amenity":"fuel"},"name":"PV Oil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pacific Pride":{"tags":{"name":"Pacific Pride","amenity":"fuel"},"name":"Pacific Pride","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pecsa":{"tags":{"name":"Pecsa","amenity":"fuel"},"name":"Pecsa","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pemex":{"tags":{"name":"Pemex","amenity":"fuel"},"name":"Pemex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pertamina":{"tags":{"name":"Pertamina","amenity":"fuel"},"name":"Pertamina","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petro":{"tags":{"name":"Petro","amenity":"fuel"},"name":"Petro","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrobras":{"tags":{"name":"Petrobras","amenity":"fuel"},"name":"Petrobras","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrochina":{"tags":{"name":"Petrochina","amenity":"fuel"},"name":"Petrochina","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petroecuador":{"tags":{"name":"Petroecuador","amenity":"fuel"},"name":"Petroecuador","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrol Ofisi":{"tags":{"name":"Petrol Ofisi","amenity":"fuel"},"name":"Petrol Ofisi","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrolimex":{"tags":{"name":"Petrolimex","amenity":"fuel"},"name":"Petrolimex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrom":{"tags":{"name":"Petrom","amenity":"fuel"},"name":"Petrom","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petron":{"tags":{"name":"Petron","amenity":"fuel"},"name":"Petron","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petronas":{"tags":{"name":"Petronas","amenity":"fuel"},"name":"Petronas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petroperu":{"tags":{"name":"Petroperu","amenity":"fuel"},"name":"Petroperu","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Phoenix":{"tags":{"name":"Phoenix","amenity":"fuel"},"name":"Phoenix","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pilot":{"tags":{"name":"Pilot","amenity":"fuel"},"name":"Pilot","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pioneer":{"tags":{"name":"Pioneer","amenity":"fuel"},"name":"Pioneer","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto":{"tags":{"name":"Posto","amenity":"fuel"},"name":"Posto","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto Atem":{"tags":{"name":"Posto Atem","amenity":"fuel"},"name":"Posto Atem","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Primax":{"tags":{"name":"Primax","amenity":"fuel"},"name":"Primax","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Prio":{"tags":{"name":"Prio","amenity":"fuel"},"name":"Prio","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Puma":{"tags":{"name":"Puma","amenity":"fuel"},"name":"Puma","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Q1":{"tags":{"name":"Q1","amenity":"fuel"},"name":"Q1","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Q8":{"tags":{"name":"Q8","amenity":"fuel"},"name":"Q8","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Q8 Easy":{"tags":{"name":"Q8 Easy","amenity":"fuel"},"name":"Q8 Easy","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/QuikTrip":{"tags":{"name":"QuikTrip","amenity":"fuel"},"name":"QuikTrip","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/REPSOL":{"tags":{"name":"REPSOL","amenity":"fuel"},"name":"REPSOL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/RaceTrac":{"tags":{"name":"RaceTrac","amenity":"fuel"},"name":"RaceTrac","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Repsol":{"tags":{"name":"Repsol","amenity":"fuel"},"name":"Repsol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Rompetrol":{"tags":{"name":"Rompetrol","amenity":"fuel"},"name":"Rompetrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Rubis":{"tags":{"name":"Rubis","amenity":"fuel"},"name":"Rubis","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/SB Tank":{"tags":{"name":"SB Tank","amenity":"fuel"},"name":"SB Tank","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/SPBU":{"tags":{"name":"SPBU","amenity":"fuel"},"name":"SPBU","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sasol":{"tags":{"name":"Sasol","amenity":"fuel"},"name":"Sasol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sea Oil":{"tags":{"name":"Sea Oil","amenity":"fuel"},"name":"Sea Oil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sheetz":{"tags":{"name":"Sheetz","amenity":"fuel"},"name":"Sheetz","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Shell":{"tags":{"name":"Shell","amenity":"fuel"},"name":"Shell","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sinclair":{"tags":{"name":"Sinclair","amenity":"fuel"},"name":"Sinclair","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sinopec":{"tags":{"name":"Sinopec","amenity":"fuel"},"name":"Sinopec","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sinopec Fuel":{"tags":{"name":"Sinopec Fuel","amenity":"fuel"},"name":"Sinopec Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Slovnaft":{"tags":{"name":"Slovnaft","amenity":"fuel"},"name":"Slovnaft","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Socar":{"tags":{"name":"Socar","amenity":"fuel"},"name":"Socar","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sokimex":{"tags":{"name":"Sokimex","amenity":"fuel"},"name":"Sokimex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Speedway":{"tags":{"name":"Speedway","amenity":"fuel"},"name":"Speedway","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/St1":{"tags":{"name":"St1","amenity":"fuel"},"name":"St1","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Star":{"tags":{"name":"Star","amenity":"fuel"},"name":"Star","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Star Oil":{"tags":{"name":"Star Oil","amenity":"fuel"},"name":"Star Oil","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Statoil":{"tags":{"name":"Statoil","amenity":"fuel"},"name":"Statoil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sunoco":{"tags":{"name":"Sunoco","amenity":"fuel"},"name":"Sunoco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tamoil":{"tags":{"name":"Tamoil","amenity":"fuel"},"name":"Tamoil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tango":{"tags":{"name":"Tango","amenity":"fuel"},"name":"Tango","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Teboil":{"tags":{"name":"Teboil","amenity":"fuel"},"name":"Teboil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tela":{"tags":{"name":"Tela","amenity":"fuel"},"name":"Tela","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Terpel":{"tags":{"name":"Terpel","amenity":"fuel"},"name":"Terpel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Texaco":{"tags":{"name":"Texaco","amenity":"fuel"},"name":"Texaco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tinq":{"tags":{"name":"Tinq","amenity":"fuel"},"name":"Tinq","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Topaz":{"tags":{"name":"Topaz","amenity":"fuel"},"name":"Topaz","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Total":{"tags":{"name":"Total","amenity":"fuel"},"name":"Total","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Total Erg":{"tags":{"name":"Total Erg","amenity":"fuel"},"name":"Total Erg","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/TotalErg":{"tags":{"name":"TotalErg","amenity":"fuel"},"name":"TotalErg","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Turkey Hill":{"tags":{"name":"Turkey Hill","amenity":"fuel"},"name":"Turkey Hill","icon":"fuel","geometry":["point","area"],"fields":["name","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":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ultramar":{"tags":{"name":"Ultramar","amenity":"fuel"},"name":"Ultramar","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/United":{"tags":{"name":"United","amenity":"fuel"},"name":"United","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Uno":{"tags":{"name":"Uno","amenity":"fuel"},"name":"Uno","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Uno-X":{"tags":{"name":"Uno-X","amenity":"fuel"},"name":"Uno-X","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Valero":{"tags":{"name":"Valero","amenity":"fuel"},"name":"Valero","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Vito":{"tags":{"name":"Vito","amenity":"fuel"},"name":"Vito","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/WOG":{"tags":{"name":"WOG","amenity":"fuel"},"name":"WOG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Westfalen":{"tags":{"name":"Westfalen","amenity":"fuel"},"name":"Westfalen","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Woolworths Petrol":{"tags":{"name":"Woolworths Petrol","amenity":"fuel"},"name":"Woolworths Petrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Z":{"tags":{"name":"Z","amenity":"fuel"},"name":"Z","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/bft":{"tags":{"name":"bft","amenity":"fuel"},"name":"bft","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/eni":{"tags":{"name":"eni","amenity":"fuel"},"name":"eni","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ΕΚΟ":{"tags":{"name":"ΕΚΟ","amenity":"fuel"},"name":"ΕΚΟ","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/АГЗС":{"tags":{"name":"АГЗС","amenity":"fuel"},"name":"АГЗС","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/АЗС":{"tags":{"name":"АЗС","amenity":"fuel"},"name":"АЗС","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Авіас":{"tags":{"name":"Авіас","amenity":"fuel"},"name":"Авіас","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/БРСМ-Нафта":{"tags":{"name":"БРСМ-Нафта","amenity":"fuel"},"name":"БРСМ-Нафта","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Башнефть":{"tags":{"name":"Башнефть","amenity":"fuel"},"name":"Башнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Белоруснефть":{"tags":{"name":"Белоруснефть","amenity":"fuel"},"name":"Белоруснефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Газовая заправка":{"tags":{"name":"Газовая заправка","amenity":"fuel"},"name":"Газовая заправка","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Газпромнефть":{"tags":{"name":"Газпромнефть","amenity":"fuel"},"name":"Газпромнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Гелиос":{"tags":{"name":"Гелиос","amenity":"fuel"},"name":"Гелиос","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ЕКА":{"tags":{"name":"ЕКА","amenity":"fuel"},"name":"ЕКА","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Заправка":{"tags":{"name":"Заправка","amenity":"fuel"},"name":"Заправка","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/КазМунайГаз":{"tags":{"name":"КазМунайГаз","amenity":"fuel"},"name":"КазМунайГаз","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Лукойл":{"tags":{"name":"Лукойл","amenity":"fuel"},"name":"Лукойл","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Макпетрол":{"tags":{"name":"Макпетрол","amenity":"fuel"},"name":"Макпетрол","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/НК Альянс":{"tags":{"name":"НК Альянс","amenity":"fuel"},"name":"НК Альянс","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Нефтьмагистраль":{"tags":{"name":"Нефтьмагистраль","amenity":"fuel"},"name":"Нефтьмагистраль","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ОККО":{"tags":{"name":"ОККО","amenity":"fuel"},"name":"ОККО","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ОМВ":{"tags":{"name":"ОМВ","amenity":"fuel"},"name":"ОМВ","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Октан":{"tags":{"name":"Октан","amenity":"fuel"},"name":"Октан","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ПТК":{"tags":{"name":"ПТК","amenity":"fuel"},"name":"ПТК","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Петрол":{"tags":{"name":"Петрол","amenity":"fuel"},"name":"Петрол","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Пропан":{"tags":{"name":"Пропан","amenity":"fuel"},"name":"Пропан","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Роснефть":{"tags":{"name":"Роснефть","amenity":"fuel"},"name":"Роснефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Сибнефть":{"tags":{"name":"Сибнефть","amenity":"fuel"},"name":"Сибнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Сургутнефтегаз":{"tags":{"name":"Сургутнефтегаз","amenity":"fuel"},"name":"Сургутнефтегаз","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ТНК":{"tags":{"name":"ТНК","amenity":"fuel"},"name":"ТНК","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Татнефтепродукт":{"tags":{"name":"Татнефтепродукт","amenity":"fuel"},"name":"Татнефтепродукт","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Татнефть":{"tags":{"name":"Татнефть","amenity":"fuel"},"name":"Татнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Укрнафта":{"tags":{"name":"Укрнафта","amenity":"fuel"},"name":"Укрнафта","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/דור אלון":{"tags":{"name":"דור אלון","amenity":"fuel"},"name":"דור אלון","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/דלק":{"tags":{"name":"דלק","amenity":"fuel"},"name":"דלק","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/סונול":{"tags":{"name":"סונול","amenity":"fuel"},"name":"סונול","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/פז":{"tags":{"name":"פז","amenity":"fuel"},"name":"פז","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/محطة وقود":{"tags":{"name":"محطة وقود","amenity":"fuel"},"name":"محطة وقود","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/محطه وقود":{"tags":{"name":"محطه وقود","amenity":"fuel"},"name":"محطه وقود","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/پمپ بنزین":{"tags":{"name":"پمپ بنزین","amenity":"fuel"},"name":"پمپ بنزین","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/پمپ گاز":{"tags":{"name":"پمپ گاز","amenity":"fuel"},"name":"پمپ گاز","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/บางจาก":{"tags":{"name":"บางจาก","amenity":"fuel"},"name":"บางจาก","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ป.ต.ท.":{"tags":{"name":"ป.ต.ท.","amenity":"fuel"},"name":"ป.ต.ท.","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/เชลล์":{"tags":{"name":"เชลล์","amenity":"fuel"},"name":"เชลล์","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/เอสโซ่":{"tags":{"name":"เอสโซ่","amenity":"fuel"},"name":"เอสโซ่","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/エッソ":{"tags":{"name":"エッソ","amenity":"fuel"},"name":"エッソ","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/エネオス":{"tags":{"name":"エネオス","amenity":"fuel"},"name":"エネオス","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/コスモ石油":{"tags":{"name":"コスモ石油","amenity":"fuel"},"name":"コスモ石油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ゼネラル":{"tags":{"name":"ゼネラル","amenity":"fuel"},"name":"ゼネラル","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/中国石化":{"tags":{"name":"中国石化","amenity":"fuel"},"name":"中国石化","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/中国石化 Sinopec":{"tags":{"name":"中国石化 Sinopec","amenity":"fuel"},"name":"中国石化 Sinopec","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/中国石油":{"tags":{"name":"中国石油","amenity":"fuel"},"name":"中国石油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/中油":{"tags":{"name":"中油","amenity":"fuel"},"name":"中油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/出光":{"tags":{"name":"出光","name:en":"IDEMITSU","amenity":"fuel"},"name":"出光","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/加油站":{"tags":{"name":"加油站","amenity":"fuel"},"name":"加油站","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/台灣中油":{"tags":{"name":"台灣中油","amenity":"fuel"},"name":"台灣中油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/昭和シェル":{"tags":{"name":"昭和シェル","amenity":"fuel"},"name":"昭和シェル","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/hospital/Cruz Roja":{"tags":{"name":"Cruz Roja","amenity":"hospital"},"name":"Cruz Roja","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/IMSS":{"tags":{"name":"IMSS","amenity":"hospital"},"name":"IMSS","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Инфекционное отделение":{"tags":{"name":"Инфекционное отделение","amenity":"hospital"},"name":"Инфекционное отделение","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Кожно-венерологический диспансер":{"tags":{"name":"Кожно-венерологический диспансер","amenity":"hospital"},"name":"Кожно-венерологический диспансер","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Районная больница":{"tags":{"name":"Районная больница","amenity":"hospital"},"name":"Районная больница","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Роддом":{"tags":{"name":"Роддом","amenity":"hospital"},"name":"Роддом","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Родильный дом":{"tags":{"name":"Родильный дом","amenity":"hospital"},"name":"Родильный дом","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Скорая помощь":{"tags":{"name":"Скорая помощь","amenity":"hospital"},"name":"Скорая помощь","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/ЦРБ":{"tags":{"name":"ЦРБ","amenity":"hospital"},"name":"ЦРБ","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/Центральная районная больница":{"tags":{"name":"Центральная районная больница","amenity":"hospital"},"name":"Центральная районная больница","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/hospital/โรงพยาบาลส่งเสริมสุขภาพตำบล":{"tags":{"name":"โรงพยาบาลส่งเสริมสุขภาพตำบล","amenity":"hospital"},"name":"โรงพยาบาลส่งเสริมสุขภาพตำบล","icon":"hospital","geometry":["point","area"],"fields":["name","operator","address","emergency"],"suggestion":true},"amenity/ice_cream/Grido":{"tags":{"name":"Grido","amenity":"ice_cream"},"name":"Grido","icon":"ice-cream","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","takeaway","delivery","outdoor_seating"],"suggestion":true},"amenity/kindergarten/Anganwadi":{"tags":{"name":"Anganwadi","amenity":"kindergarten"},"name":"Anganwadi","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Arche Noah":{"tags":{"name":"Arche Noah","amenity":"kindergarten"},"name":"Arche Noah","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/CONAFE Preescolar":{"tags":{"name":"CONAFE Preescolar","amenity":"kindergarten"},"name":"CONAFE Preescolar","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Educacion Inicial de CONAFE No Escolarizado":{"tags":{"name":"Educacion Inicial de CONAFE No Escolarizado","amenity":"kindergarten"},"name":"Educacion Inicial de CONAFE No Escolarizado","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Estefania Casta�eda":{"tags":{"name":"Estefania Casta�eda","amenity":"kindergarten"},"name":"Estefania Casta�eda","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Evangelischer Kindergarten":{"tags":{"name":"Evangelischer Kindergarten","amenity":"kindergarten"},"name":"Evangelischer Kindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Federico Froebel":{"tags":{"name":"Federico Froebel","amenity":"kindergarten"},"name":"Federico Froebel","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Gabriela Mistral":{"tags":{"name":"Gabriela Mistral","amenity":"kindergarten"},"name":"Gabriela Mistral","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Jardin Infantil":{"tags":{"name":"Jardin Infantil","amenity":"kindergarten"},"name":"Jardin Infantil","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Jean Piaget":{"tags":{"name":"Jean Piaget","amenity":"kindergarten"},"name":"Jean Piaget","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Katholischer Kindergarten":{"tags":{"name":"Katholischer Kindergarten","amenity":"kindergarten"},"name":"Katholischer Kindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Kindergarten Regenbogen":{"tags":{"name":"Kindergarten Regenbogen","amenity":"kindergarten"},"name":"Kindergarten Regenbogen","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Kindergarten St. Josef":{"tags":{"name":"Kindergarten St. Josef","amenity":"kindergarten"},"name":"Kindergarten St. Josef","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Kindergarten St. Martin":{"tags":{"name":"Kindergarten St. Martin","amenity":"kindergarten"},"name":"Kindergarten St. Martin","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Maria Montessori":{"tags":{"name":"Maria Montessori","amenity":"kindergarten"},"name":"Maria Montessori","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/PAUD":{"tags":{"name":"PAUD","amenity":"kindergarten"},"name":"PAUD","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Pusteblume":{"tags":{"name":"Pusteblume","amenity":"kindergarten"},"name":"Pusteblume","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Rosaura Zapata":{"tags":{"name":"Rosaura Zapata","amenity":"kindergarten"},"name":"Rosaura Zapata","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Sor Juana Ines De La Cruz":{"tags":{"name":"Sor Juana Ines De La Cruz","amenity":"kindergarten"},"name":"Sor Juana Ines De La Cruz","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Spatzennest":{"tags":{"name":"Spatzennest","amenity":"kindergarten"},"name":"Spatzennest","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Städtischer Kindergarten":{"tags":{"name":"Städtischer Kindergarten","amenity":"kindergarten"},"name":"Städtischer Kindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Villa Kunterbunt":{"tags":{"name":"Villa Kunterbunt","amenity":"kindergarten"},"name":"Villa Kunterbunt","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Waldkindergarten":{"tags":{"name":"Waldkindergarten","amenity":"kindergarten"},"name":"Waldkindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Waldorfkindergarten":{"tags":{"name":"Waldorfkindergarten","amenity":"kindergarten"},"name":"Waldorfkindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Óvoda":{"tags":{"name":"Óvoda","amenity":"kindergarten"},"name":"Óvoda","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детсад":{"tags":{"name":"Детсад","amenity":"kindergarten"},"name":"Детсад","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад Солнышко":{"tags":{"name":"Детский сад Солнышко","amenity":"kindergarten"},"name":"Детский сад Солнышко","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад № 1":{"tags":{"name":"Детский сад № 1","amenity":"kindergarten"},"name":"Детский сад № 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №1":{"tags":{"name":"Детский сад №1","amenity":"kindergarten"},"name":"Детский сад №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №10":{"tags":{"name":"Детский сад №10","amenity":"kindergarten"},"name":"Детский сад №10","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №11":{"tags":{"name":"Детский сад №11","amenity":"kindergarten"},"name":"Детский сад №11","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №12":{"tags":{"name":"Детский сад №12","amenity":"kindergarten"},"name":"Детский сад №12","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №13":{"tags":{"name":"Детский сад №13","amenity":"kindergarten"},"name":"Детский сад №13","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №14":{"tags":{"name":"Детский сад №14","amenity":"kindergarten"},"name":"Детский сад №14","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №15":{"tags":{"name":"Детский сад №15","amenity":"kindergarten"},"name":"Детский сад №15","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №16":{"tags":{"name":"Детский сад №16","amenity":"kindergarten"},"name":"Детский сад №16","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №17":{"tags":{"name":"Детский сад №17","amenity":"kindergarten"},"name":"Детский сад №17","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №18":{"tags":{"name":"Детский сад №18","amenity":"kindergarten"},"name":"Детский сад №18","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №19":{"tags":{"name":"Детский сад №19","amenity":"kindergarten"},"name":"Детский сад №19","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №2":{"tags":{"name":"Детский сад №2","amenity":"kindergarten"},"name":"Детский сад №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №22":{"tags":{"name":"Детский сад №22","amenity":"kindergarten"},"name":"Детский сад №22","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №24":{"tags":{"name":"Детский сад №24","amenity":"kindergarten"},"name":"Детский сад №24","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №25":{"tags":{"name":"Детский сад №25","amenity":"kindergarten"},"name":"Детский сад №25","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №27":{"tags":{"name":"Детский сад №27","amenity":"kindergarten"},"name":"Детский сад №27","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №29":{"tags":{"name":"Детский сад №29","amenity":"kindergarten"},"name":"Детский сад №29","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №3":{"tags":{"name":"Детский сад №3","amenity":"kindergarten"},"name":"Детский сад №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №33":{"tags":{"name":"Детский сад №33","amenity":"kindergarten"},"name":"Детский сад №33","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №4":{"tags":{"name":"Детский сад №4","amenity":"kindergarten"},"name":"Детский сад №4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №5":{"tags":{"name":"Детский сад №5","amenity":"kindergarten"},"name":"Детский сад №5","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №6":{"tags":{"name":"Детский сад №6","amenity":"kindergarten"},"name":"Детский сад №6","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №7":{"tags":{"name":"Детский сад №7","amenity":"kindergarten"},"name":"Детский сад №7","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №8":{"tags":{"name":"Детский сад №8","amenity":"kindergarten"},"name":"Детский сад №8","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №9":{"tags":{"name":"Детский сад №9","amenity":"kindergarten"},"name":"Детский сад №9","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Дитячий садок":{"tags":{"name":"Дитячий садок","amenity":"kindergarten"},"name":"Дитячий садок","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Солнышко":{"tags":{"name":"Солнышко","amenity":"kindergarten"},"name":"Солнышко","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/საბავშვო ბაღი":{"tags":{"name":"საბავშვო ბაღი","amenity":"kindergarten"},"name":"საბავშვო ბაღი","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/中央保育所":{"tags":{"name":"中央保育所","amenity":"kindergarten"},"name":"中央保育所","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/library/Biblioteca Comunale":{"tags":{"name":"Biblioteca Comunale","amenity":"library"},"name":"Biblioteca Comunale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Biblioteca Municipal":{"tags":{"name":"Biblioteca Municipal","amenity":"library"},"name":"Biblioteca Municipal","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Biblioteca Pública":{"tags":{"name":"Biblioteca Pública","amenity":"library"},"name":"Biblioteca Pública","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Biblioteca Pública Municipal":{"tags":{"name":"Biblioteca Pública Municipal","amenity":"library"},"name":"Biblioteca Pública Municipal","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Biblioteca comunale":{"tags":{"name":"Biblioteca comunale","amenity":"library"},"name":"Biblioteca comunale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Biblioteka Publiczna":{"tags":{"name":"Biblioteka Publiczna","amenity":"library"},"name":"Biblioteka Publiczna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Bibliothèque Municipale":{"tags":{"name":"Bibliothèque Municipale","amenity":"library"},"name":"Bibliothèque Municipale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Bibliothèque municipale":{"tags":{"name":"Bibliothèque municipale","amenity":"library"},"name":"Bibliothèque municipale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Bücherei":{"tags":{"name":"Bücherei","amenity":"library"},"name":"Bücherei","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Central Library":{"tags":{"name":"Central Library","amenity":"library"},"name":"Central Library","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Gemeindebücherei":{"tags":{"name":"Gemeindebücherei","amenity":"library"},"name":"Gemeindebücherei","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Gminna Biblioteka Publiczna":{"tags":{"name":"Gminna Biblioteka Publiczna","amenity":"library"},"name":"Gminna Biblioteka Publiczna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Miejska Biblioteka Publiczna":{"tags":{"name":"Miejska Biblioteka Publiczna","amenity":"library"},"name":"Miejska Biblioteka Publiczna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Médiathèque":{"tags":{"name":"Médiathèque","amenity":"library"},"name":"Médiathèque","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Městská knihovna":{"tags":{"name":"Městská knihovna","amenity":"library"},"name":"Městská knihovna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Public Library":{"tags":{"name":"Public Library","amenity":"library"},"name":"Public Library","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Stadtbibliothek":{"tags":{"name":"Stadtbibliothek","amenity":"library"},"name":"Stadtbibliothek","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Stadtbücherei":{"tags":{"name":"Stadtbücherei","amenity":"library"},"name":"Stadtbücherei","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Городская библиотека":{"tags":{"name":"Городская библиотека","amenity":"library"},"name":"Городская библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Детская библиотека":{"tags":{"name":"Детская библиотека","amenity":"library"},"name":"Детская библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Центральная библиотека":{"tags":{"name":"Центральная библиотека","amenity":"library"},"name":"Центральная библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/Центральная городская библиотека":{"tags":{"name":"Центральная городская библиотека","amenity":"library"},"name":"Центральная городская библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/library/图书馆":{"tags":{"name":"图书馆","amenity":"library"},"name":"图书馆","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"amenity/pharmacy/36.6":{"tags":{"name":"36.6","amenity":"pharmacy"},"name":"36.6","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apollo Pharmacy":{"tags":{"name":"Apollo Pharmacy","amenity":"pharmacy"},"name":"Apollo Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apotek":{"tags":{"name":"Apotek","amenity":"pharmacy"},"name":"Apotek","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apotek Hjärtat":{"tags":{"name":"Apotek Hjärtat","amenity":"pharmacy"},"name":"Apotek Hjärtat","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Bartell Drugs":{"tags":{"name":"Bartell Drugs","amenity":"pharmacy"},"name":"Bartell Drugs","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Benavides":{"tags":{"name":"Benavides","amenity":"pharmacy"},"name":"Benavides","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Benu":{"tags":{"name":"Benu","amenity":"pharmacy"},"name":"Benu","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Botica":{"tags":{"name":"Botica","amenity":"pharmacy"},"name":"Botica","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Camelia":{"tags":{"name":"Camelia","amenity":"pharmacy"},"name":"Camelia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Catena":{"tags":{"name":"Catena","amenity":"pharmacy"},"name":"Catena","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Chemist Warehouse":{"tags":{"name":"Chemist Warehouse","amenity":"pharmacy"},"name":"Chemist Warehouse","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Cruz Azul":{"tags":{"name":"Cruz Azul","amenity":"pharmacy"},"name":"Cruz Azul","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Dbam o Zdrowie":{"tags":{"name":"Dbam o Zdrowie","amenity":"pharmacy"},"name":"Dbam o Zdrowie","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Droga Raia":{"tags":{"name":"Droga Raia","amenity":"pharmacy"},"name":"Droga Raia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Drogaria São Paulo":{"tags":{"name":"Drogaria São Paulo","amenity":"pharmacy"},"name":"Drogaria São Paulo","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Drogasil":{"tags":{"name":"Drogasil","amenity":"pharmacy"},"name":"Drogasil","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Eczane":{"tags":{"name":"Eczane","amenity":"pharmacy"},"name":"Eczane","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Familiprix":{"tags":{"name":"Familiprix","amenity":"pharmacy"},"name":"Familiprix","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacenter":{"tags":{"name":"Farmacenter","amenity":"pharmacy"},"name":"Farmacenter","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacia Centrale":{"tags":{"name":"Farmacia Centrale","amenity":"pharmacy"},"name":"Farmacia Centrale","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacia Guadalajara":{"tags":{"name":"Farmacia Guadalajara","amenity":"pharmacy"},"name":"Farmacia Guadalajara","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacia del Ahorro":{"tags":{"name":"Farmacia del Ahorro","amenity":"pharmacy"},"name":"Farmacia del Ahorro","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Cruz Azul":{"tags":{"name":"Farmacias Cruz Azul","amenity":"pharmacy"},"name":"Farmacias Cruz Azul","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Económicas":{"tags":{"name":"Farmacias Económicas","amenity":"pharmacy"},"name":"Farmacias Económicas","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Guadalajara":{"tags":{"name":"Farmacias Guadalajara","amenity":"pharmacy"},"name":"Farmacias Guadalajara","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Sana Sana":{"tags":{"name":"Farmacias Sana Sana","amenity":"pharmacy"},"name":"Farmacias Sana Sana","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Similares":{"tags":{"name":"Farmacias Similares","amenity":"pharmacy"},"name":"Farmacias Similares","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias del Ahorro":{"tags":{"name":"Farmacias del Ahorro","amenity":"pharmacy"},"name":"Farmacias del Ahorro","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmácia":{"tags":{"name":"Farmácia","amenity":"pharmacy"},"name":"Farmácia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Felicia":{"tags":{"name":"Felicia","amenity":"pharmacy"},"name":"Felicia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Fybeca":{"tags":{"name":"Fybeca","amenity":"pharmacy"},"name":"Fybeca","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Generika Drugstore":{"tags":{"name":"Generika Drugstore","amenity":"pharmacy"},"name":"Generika Drugstore","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Guardian":{"tags":{"name":"Guardian","amenity":"pharmacy"},"name":"Guardian","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Gyógyszertár":{"tags":{"name":"Gyógyszertár","amenity":"pharmacy"},"name":"Gyógyszertár","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/H-E-B Pharmacy":{"tags":{"name":"H-E-B Pharmacy","amenity":"pharmacy"},"name":"H-E-B Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Inkafarma":{"tags":{"name":"Inkafarma","amenity":"pharmacy"},"name":"Inkafarma","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Kur-Apotheke":{"tags":{"name":"Kur-Apotheke","amenity":"pharmacy"},"name":"Kur-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Lékárna":{"tags":{"name":"Lékárna","amenity":"pharmacy"},"name":"Lékárna","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Mifarma":{"tags":{"name":"Mifarma","amenity":"pharmacy"},"name":"Mifarma","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Mēness aptieka":{"tags":{"name":"Mēness aptieka","amenity":"pharmacy"},"name":"Mēness aptieka","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pague Menos":{"tags":{"name":"Pague Menos","amenity":"pharmacy"},"name":"Pague Menos","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Panvel":{"tags":{"name":"Panvel","amenity":"pharmacy"},"name":"Panvel","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Park-Apotheke":{"tags":{"name":"Park-Apotheke","amenity":"pharmacy"},"name":"Park-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie Principale":{"tags":{"name":"Pharmacie Principale","amenity":"pharmacy"},"name":"Pharmacie Principale","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie de l'Hôtel de Ville":{"tags":{"name":"Pharmacie de l'Hôtel de Ville","amenity":"pharmacy"},"name":"Pharmacie de l'Hôtel de Ville","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie de la Gare":{"tags":{"name":"Pharmacie de la Gare","amenity":"pharmacy"},"name":"Pharmacie de la Gare","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie de la Mairie":{"tags":{"name":"Pharmacie de la Mairie","amenity":"pharmacy"},"name":"Pharmacie de la Mairie","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie de la Poste":{"tags":{"name":"Pharmacie de la Poste","amenity":"pharmacy"},"name":"Pharmacie de la Poste","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie du Centre":{"tags":{"name":"Pharmacie du Centre","amenity":"pharmacy"},"name":"Pharmacie du Centre","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie du Marché":{"tags":{"name":"Pharmacie du Marché","amenity":"pharmacy"},"name":"Pharmacie du Marché","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie du Parc":{"tags":{"name":"Pharmacie du Parc","amenity":"pharmacy"},"name":"Pharmacie du Parc","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Punkt Apteczny":{"tags":{"name":"Punkt Apteczny","amenity":"pharmacy"},"name":"Punkt Apteczny","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rexall":{"tags":{"name":"Rexall","amenity":"pharmacy"},"name":"Rexall","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rose Pharmacy":{"tags":{"name":"Rose Pharmacy","amenity":"pharmacy"},"name":"Rose Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rowlands Pharmacy":{"tags":{"name":"Rowlands Pharmacy","amenity":"pharmacy"},"name":"Rowlands Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Sana Sana":{"tags":{"name":"Sana Sana","amenity":"pharmacy"},"name":"Sana Sana","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Schloss-Apotheke":{"tags":{"name":"Schloss-Apotheke","amenity":"pharmacy"},"name":"Schloss-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Sensiblu":{"tags":{"name":"Sensiblu","amenity":"pharmacy"},"name":"Sensiblu","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/South Star Drug":{"tags":{"name":"South Star Drug","amenity":"pharmacy"},"name":"South Star Drug","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/São João":{"tags":{"name":"São João","amenity":"pharmacy"},"name":"São João","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Uniprix":{"tags":{"name":"Uniprix","amenity":"pharmacy"},"name":"Uniprix","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Walgreens Pharmacy":{"tags":{"name":"Walgreens Pharmacy","amenity":"pharmacy"},"name":"Walgreens Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Walmart Pharmacy":{"tags":{"name":"Walmart Pharmacy","amenity":"pharmacy"},"name":"Walmart Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Well Pharmacy":{"tags":{"name":"Well Pharmacy","amenity":"pharmacy"},"name":"Well Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/centro naturista":{"tags":{"name":"centro naturista","amenity":"pharmacy"},"name":"centro naturista","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/А5":{"tags":{"name":"А5","amenity":"pharmacy"},"name":"А5","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Айболит":{"tags":{"name":"Айболит","amenity":"pharmacy"},"name":"Айболит","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека низких цен":{"tags":{"name":"Аптека низких цен","amenity":"pharmacy"},"name":"Аптека низких цен","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека низьких цін":{"tags":{"name":"Аптека низьких цін","amenity":"pharmacy"},"name":"Аптека низьких цін","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека от склада":{"tags":{"name":"Аптека от склада","amenity":"pharmacy"},"name":"Аптека от склада","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека №1":{"tags":{"name":"Аптека №1","amenity":"pharmacy"},"name":"Аптека №1","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптечный пункт":{"tags":{"name":"Аптечный пункт","amenity":"pharmacy"},"name":"Аптечный пункт","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Арніка":{"tags":{"name":"Арніка","amenity":"pharmacy"},"name":"Арніка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Бережная аптека":{"tags":{"name":"Бережная аптека","amenity":"pharmacy"},"name":"Бережная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Будь здоров":{"tags":{"name":"Будь здоров","amenity":"pharmacy"},"name":"Будь здоров","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Вита":{"tags":{"name":"Вита","amenity":"pharmacy"},"name":"Вита","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Горздрав":{"tags":{"name":"Горздрав","amenity":"pharmacy"},"name":"Горздрав","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Живика":{"tags":{"name":"Живика","amenity":"pharmacy"},"name":"Живика","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Здоровье":{"tags":{"name":"Здоровье","amenity":"pharmacy"},"name":"Здоровье","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Имплозия":{"tags":{"name":"Имплозия","amenity":"pharmacy"},"name":"Имплозия","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Классика":{"tags":{"name":"Классика","amenity":"pharmacy"},"name":"Классика","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ладушка":{"tags":{"name":"Ладушка","amenity":"pharmacy"},"name":"Ладушка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Мед-сервіс":{"tags":{"name":"Мед-сервіс","amenity":"pharmacy"},"name":"Мед-сервіс","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Мелодия здоровья":{"tags":{"name":"Мелодия здоровья","amenity":"pharmacy"},"name":"Мелодия здоровья","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Невис":{"tags":{"name":"Невис","amenity":"pharmacy"},"name":"Невис","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Норма":{"tags":{"name":"Норма","amenity":"pharmacy"},"name":"Норма","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Озерки":{"tags":{"name":"Озерки","amenity":"pharmacy"},"name":"Озерки","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Панацея":{"tags":{"name":"Панацея","amenity":"pharmacy"},"name":"Панацея","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Первая помощь":{"tags":{"name":"Первая помощь","amenity":"pharmacy"},"name":"Первая помощь","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Планета здоровья":{"tags":{"name":"Планета здоровья","amenity":"pharmacy"},"name":"Планета здоровья","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ригла":{"tags":{"name":"Ригла","amenity":"pharmacy"},"name":"Ригла","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Семейная":{"tags":{"name":"Семейная","amenity":"pharmacy"},"name":"Семейная","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Социальная аптека":{"tags":{"name":"Социальная аптека","amenity":"pharmacy"},"name":"Социальная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Столички":{"tags":{"name":"Столички","amenity":"pharmacy"},"name":"Столички","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармакопейка":{"tags":{"name":"Фармакопейка","amenity":"pharmacy"},"name":"Фармакопейка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармакор":{"tags":{"name":"Фармакор","amenity":"pharmacy"},"name":"Фармакор","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармация":{"tags":{"name":"Фармация","amenity":"pharmacy"},"name":"Фармация","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармленд":{"tags":{"name":"Фармленд","amenity":"pharmacy"},"name":"Фармленд","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Центральная аптека":{"tags":{"name":"Центральная аптека","amenity":"pharmacy"},"name":"Центральная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/סופר-פארם":{"tags":{"name":"סופר-פארם","amenity":"pharmacy"},"name":"סופר-פארם","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/داروخانه":{"tags":{"name":"داروخانه","amenity":"pharmacy"},"name":"داروخانه","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/داروخانه شبانه روزی":{"tags":{"name":"داروخانه شبانه روزی","amenity":"pharmacy"},"name":"داروخانه شبانه روزی","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/صيدلية":{"tags":{"name":"صيدلية","amenity":"pharmacy"},"name":"صيدلية","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/くすりの福太郎":{"tags":{"name":"くすりの福太郎","amenity":"pharmacy"},"name":"くすりの福太郎","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/さくら薬局":{"tags":{"name":"さくら薬局","amenity":"pharmacy"},"name":"さくら薬局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ウエルシア":{"tags":{"name":"ウエルシア","amenity":"pharmacy"},"name":"ウエルシア","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/カワチ薬品":{"tags":{"name":"カワチ薬品","amenity":"pharmacy"},"name":"カワチ薬品","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/クリエイト":{"tags":{"name":"クリエイト","amenity":"pharmacy"},"name":"クリエイト","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/サンドラッグ":{"tags":{"name":"サンドラッグ","amenity":"pharmacy"},"name":"サンドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/スギ薬局":{"tags":{"name":"スギ薬局","amenity":"pharmacy"},"name":"スギ薬局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/セイジョー":{"tags":{"name":"セイジョー","amenity":"pharmacy"},"name":"セイジョー","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ツルハドラッグ":{"tags":{"name":"ツルハドラッグ","amenity":"pharmacy"},"name":"ツルハドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/マツモトキヨシ":{"tags":{"name":"マツモトキヨシ","amenity":"pharmacy"},"name":"マツモトキヨシ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/丁丁藥局":{"tags":{"name":"丁丁藥局","amenity":"pharmacy"},"name":"丁丁藥局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pub/Black Bull":{"tags":{"name":"Black Bull","amenity":"pub"},"name":"Black Bull","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Commercial Hotel":{"tags":{"name":"Commercial Hotel","amenity":"pub"},"name":"Commercial Hotel","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Cross Keys":{"tags":{"name":"Cross Keys","amenity":"pub"},"name":"Cross Keys","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Irish Pub":{"tags":{"name":"Irish Pub","amenity":"pub"},"name":"Irish Pub","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Kings Arms":{"tags":{"name":"Kings Arms","amenity":"pub"},"name":"Kings Arms","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Kings Head":{"tags":{"name":"Kings Head","amenity":"pub"},"name":"Kings Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/New Inn":{"tags":{"name":"New Inn","amenity":"pub"},"name":"New Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Prince of Wales":{"tags":{"name":"Prince of Wales","amenity":"pub"},"name":"Prince of Wales","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Queens Head":{"tags":{"name":"Queens Head","amenity":"pub"},"name":"Queens Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Red Lion":{"tags":{"name":"Red Lion","amenity":"pub"},"name":"Red Lion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Rose & Crown":{"tags":{"name":"Rose & Crown","amenity":"pub"},"name":"Rose & Crown","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Rose and Crown":{"tags":{"name":"Rose and Crown","amenity":"pub"},"name":"Rose and Crown","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Royal Oak":{"tags":{"name":"Royal Oak","amenity":"pub"},"name":"Royal Oak","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Albion":{"tags":{"name":"The Albion","amenity":"pub"},"name":"The Albion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Anchor":{"tags":{"name":"The Anchor","amenity":"pub"},"name":"The Anchor","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Angel":{"tags":{"name":"The Angel","amenity":"pub"},"name":"The Angel","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Beehive":{"tags":{"name":"The Beehive","amenity":"pub"},"name":"The Beehive","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Bell":{"tags":{"name":"The Bell","amenity":"pub"},"name":"The Bell","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Bell Inn":{"tags":{"name":"The Bell Inn","amenity":"pub"},"name":"The Bell Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Black Horse":{"tags":{"name":"The Black Horse","amenity":"pub"},"name":"The Black Horse","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Bull":{"tags":{"name":"The Bull","amenity":"pub"},"name":"The Bull","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Castle":{"tags":{"name":"The Castle","amenity":"pub"},"name":"The Castle","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Chequers":{"tags":{"name":"The Chequers","amenity":"pub"},"name":"The Chequers","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Cricketers":{"tags":{"name":"The Cricketers","amenity":"pub"},"name":"The Cricketers","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Cross Keys":{"tags":{"name":"The Cross Keys","amenity":"pub"},"name":"The Cross Keys","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Crown":{"tags":{"name":"The Crown","amenity":"pub"},"name":"The Crown","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Crown Inn":{"tags":{"name":"The Crown Inn","amenity":"pub"},"name":"The Crown Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Fox":{"tags":{"name":"The Fox","amenity":"pub"},"name":"The Fox","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The George":{"tags":{"name":"The George","amenity":"pub"},"name":"The George","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Green Man":{"tags":{"name":"The Green Man","amenity":"pub"},"name":"The Green Man","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Greyhound":{"tags":{"name":"The Greyhound","amenity":"pub"},"name":"The Greyhound","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Kings Arms":{"tags":{"name":"The Kings Arms","amenity":"pub"},"name":"The Kings Arms","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Kings Head":{"tags":{"name":"The Kings Head","amenity":"pub"},"name":"The Kings Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The New Inn":{"tags":{"name":"The New Inn","amenity":"pub"},"name":"The New Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Plough":{"tags":{"name":"The Plough","amenity":"pub"},"name":"The Plough","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Plough Inn":{"tags":{"name":"The Plough Inn","amenity":"pub"},"name":"The Plough Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Queens Head":{"tags":{"name":"The Queens Head","amenity":"pub"},"name":"The Queens Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Railway":{"tags":{"name":"The Railway","amenity":"pub"},"name":"The Railway","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Red Lion":{"tags":{"name":"The Red Lion","amenity":"pub"},"name":"The Red Lion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Rising Sun":{"tags":{"name":"The Rising Sun","amenity":"pub"},"name":"The Rising Sun","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Royal Oak":{"tags":{"name":"The Royal Oak","amenity":"pub"},"name":"The Royal Oak","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Ship":{"tags":{"name":"The Ship","amenity":"pub"},"name":"The Ship","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Ship Inn":{"tags":{"name":"The Ship Inn","amenity":"pub"},"name":"The Ship Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Star":{"tags":{"name":"The Star","amenity":"pub"},"name":"The Star","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Star Inn":{"tags":{"name":"The Star Inn","amenity":"pub"},"name":"The Star Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Sun Inn":{"tags":{"name":"The Sun Inn","amenity":"pub"},"name":"The Sun Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Swan":{"tags":{"name":"The Swan","amenity":"pub"},"name":"The Swan","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Swan Inn":{"tags":{"name":"The Swan Inn","amenity":"pub"},"name":"The Swan Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Victoria":{"tags":{"name":"The Victoria","amenity":"pub"},"name":"The Victoria","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Wheatsheaf":{"tags":{"name":"The Wheatsheaf","amenity":"pub"},"name":"The Wheatsheaf","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Hart":{"tags":{"name":"The White Hart","amenity":"pub"},"name":"The White Hart","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Horse":{"tags":{"name":"The White Horse","amenity":"pub"},"name":"The White Horse","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Lion":{"tags":{"name":"The White Lion","amenity":"pub"},"name":"The White Lion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Swan":{"tags":{"name":"The White Swan","amenity":"pub"},"name":"The White Swan","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/魚民":{"tags":{"name":"魚民","amenity":"pub"},"name":"魚民","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/鳥貴族":{"tags":{"name":"鳥貴族","amenity":"pub"},"name":"鳥貴族","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Adler":{"tags":{"name":"Adler","amenity":"restaurant"},"name":"Adler","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Adria":{"tags":{"name":"Adria","amenity":"restaurant"},"name":"Adria","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Adyar Ananda Bhavan":{"tags":{"name":"Adyar Ananda Bhavan","amenity":"restaurant"},"name":"Adyar Ananda Bhavan","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Akropolis":{"tags":{"name":"Akropolis","amenity":"restaurant"},"name":"Akropolis","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Alte Post":{"tags":{"name":"Alte Post","amenity":"restaurant"},"name":"Alte Post","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Applebee's":{"tags":{"name":"Applebee's","amenity":"restaurant"},"name":"Applebee's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Asia":{"tags":{"name":"Asia","amenity":"restaurant"},"name":"Asia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Athen":{"tags":{"name":"Athen","amenity":"restaurant"},"name":"Athen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Athos":{"tags":{"name":"Athos","amenity":"restaurant"},"name":"Athos","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Autogrill":{"tags":{"name":"Autogrill","amenity":"restaurant"},"name":"Autogrill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bahnhof":{"tags":{"name":"Bahnhof","amenity":"restaurant"},"name":"Bahnhof","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bella Italia":{"tags":{"name":"Bella Italia","amenity":"restaurant"},"name":"Bella Italia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bella Napoli":{"tags":{"name":"Bella Napoli","amenity":"restaurant"},"name":"Bella Napoli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Belvedere":{"tags":{"name":"Belvedere","amenity":"restaurant"},"name":"Belvedere","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Big Boy":{"tags":{"name":"Big Boy","amenity":"restaurant"},"name":"Big Boy","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bob Evans":{"tags":{"name":"Bob Evans","amenity":"restaurant"},"name":"Bob Evans","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bonefish Grill":{"tags":{"name":"Bonefish Grill","amenity":"restaurant"},"name":"Bonefish Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Boston Pizza":{"tags":{"name":"Boston Pizza","amenity":"restaurant"},"name":"Boston Pizza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Buffalo Grill":{"tags":{"name":"Buffalo Grill","amenity":"restaurant"},"name":"Buffalo Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Buffalo Wild Wings":{"tags":{"name":"Buffalo Wild Wings","amenity":"restaurant"},"name":"Buffalo Wild Wings","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bären":{"tags":{"name":"Bären","amenity":"restaurant"},"name":"Bären","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/California Pizza Kitchen":{"tags":{"name":"California Pizza Kitchen","amenity":"restaurant"},"name":"California Pizza Kitchen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Canteen":{"tags":{"name":"Canteen","amenity":"restaurant"},"name":"Canteen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Capri":{"tags":{"name":"Capri","amenity":"restaurant"},"name":"Capri","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Carluccio's":{"tags":{"name":"Carluccio's","amenity":"restaurant"},"name":"Carluccio's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Carpe Diem":{"tags":{"name":"Carpe Diem","amenity":"restaurant"},"name":"Carpe Diem","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Carrabba's Italian Grill":{"tags":{"name":"Carrabba's Italian Grill","amenity":"restaurant"},"name":"Carrabba's Italian Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Casa Mia":{"tags":{"name":"Casa Mia","amenity":"restaurant"},"name":"Casa Mia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Casablanca":{"tags":{"name":"Casablanca","amenity":"restaurant"},"name":"Casablanca","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Cheesecake Factory":{"tags":{"name":"Cheesecake Factory","amenity":"restaurant"},"name":"Cheesecake Factory","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chifa":{"tags":{"name":"Chifa","amenity":"restaurant"},"name":"Chifa","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chili's":{"tags":{"name":"Chili's","amenity":"restaurant"},"name":"Chili's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Buffet":{"tags":{"name":"China Buffet","amenity":"restaurant"},"name":"China Buffet","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Garden":{"tags":{"name":"China Garden","amenity":"restaurant"},"name":"China Garden","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China House":{"tags":{"name":"China House","amenity":"restaurant"},"name":"China House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Town":{"tags":{"name":"China Town","amenity":"restaurant"},"name":"China Town","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Wok":{"tags":{"name":"China Wok","amenity":"restaurant"},"name":"China Wok","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chiquito":{"tags":{"name":"Chiquito","amenity":"restaurant"},"name":"Chiquito","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chuck E. Cheese's":{"tags":{"name":"Chuck E. Cheese's","amenity":"restaurant"},"name":"Chuck E. Cheese's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Cici's Pizza":{"tags":{"name":"Cici's Pizza","amenity":"restaurant"},"name":"Cici's Pizza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Comedor":{"tags":{"name":"Comedor","amenity":"restaurant"},"name":"Comedor","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Comida China":{"tags":{"name":"Comida China","amenity":"restaurant"},"name":"Comida China","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Courtepaille":{"tags":{"name":"Courtepaille","amenity":"restaurant"},"name":"Courtepaille","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Cracker Barrel":{"tags":{"name":"Cracker Barrel","amenity":"restaurant"},"name":"Cracker Barrel","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Da Grasso":{"tags":{"name":"Da Grasso","amenity":"restaurant"},"name":"Da Grasso","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Da Vinci":{"tags":{"name":"Da Vinci","amenity":"restaurant"},"name":"Da Vinci","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Delphi":{"tags":{"name":"Delphi","amenity":"restaurant"},"name":"Delphi","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Denny's":{"tags":{"name":"Denny's","amenity":"restaurant"},"name":"Denny's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Deutsches Haus":{"tags":{"name":"Deutsches Haus","amenity":"restaurant"},"name":"Deutsches Haus","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Dionysos":{"tags":{"name":"Dionysos","amenity":"restaurant"},"name":"Dionysos","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Dolce Vita":{"tags":{"name":"Dolce Vita","amenity":"restaurant"},"name":"Dolce Vita","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Dorfkrug":{"tags":{"name":"Dorfkrug","amenity":"restaurant"},"name":"Dorfkrug","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/East Side Mario's":{"tags":{"name":"East Side Mario's","amenity":"restaurant"},"name":"East Side Mario's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/El Greco":{"tags":{"name":"El Greco","amenity":"restaurant"},"name":"El Greco","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/El Paso":{"tags":{"name":"El Paso","amenity":"restaurant"},"name":"El Paso","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/El Rancho":{"tags":{"name":"El Rancho","amenity":"restaurant"},"name":"El Rancho","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Europa":{"tags":{"name":"Europa","amenity":"restaurant"},"name":"Europa","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Famous Dave's":{"tags":{"name":"Famous Dave's","amenity":"restaurant"},"name":"Famous Dave's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Flunch":{"tags":{"name":"Flunch","amenity":"restaurant"},"name":"Flunch","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Frankie & Benny's":{"tags":{"name":"Frankie & Benny's","amenity":"restaurant"},"name":"Frankie & Benny's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Friendly's":{"tags":{"name":"Friendly's","amenity":"restaurant"},"name":"Friendly's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gasthaus Krone":{"tags":{"name":"Gasthaus Krone","amenity":"restaurant"},"name":"Gasthaus Krone","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gasthaus zur Linde":{"tags":{"name":"Gasthaus zur Linde","amenity":"restaurant"},"name":"Gasthaus zur Linde","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gasthof zur Post":{"tags":{"name":"Gasthof zur Post","amenity":"restaurant"},"name":"Gasthof zur Post","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Golden Corral":{"tags":{"name":"Golden Corral","amenity":"restaurant"},"name":"Golden Corral","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Golden Dragon":{"tags":{"name":"Golden Dragon","amenity":"restaurant"},"name":"Golden Dragon","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Great Wall":{"tags":{"name":"Great Wall","amenity":"restaurant"},"name":"Great Wall","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Grüner Baum":{"tags":{"name":"Grüner Baum","amenity":"restaurant"},"name":"Grüner Baum","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gusto":{"tags":{"name":"Gusto","amenity":"restaurant"},"name":"Gusto","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hard Rock Cafe":{"tags":{"name":"Hard Rock Cafe","amenity":"restaurant"},"name":"Hard Rock Cafe","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Harvester":{"tags":{"name":"Harvester","amenity":"restaurant"},"name":"Harvester","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hellas":{"tags":{"name":"Hellas","amenity":"restaurant"},"name":"Hellas","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hippopotamus":{"tags":{"name":"Hippopotamus","amenity":"restaurant"},"name":"Hippopotamus","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hirsch":{"tags":{"name":"Hirsch","amenity":"restaurant"},"name":"Hirsch","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hirschen":{"tags":{"name":"Hirschen","amenity":"restaurant"},"name":"Hirschen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hong Kong":{"tags":{"name":"Hong Kong","amenity":"restaurant"},"name":"Hong Kong","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hooters":{"tags":{"name":"Hooters","amenity":"restaurant"},"name":"Hooters","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/IHOP":{"tags":{"name":"IHOP","amenity":"restaurant"},"name":"IHOP","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/IL Патио":{"tags":{"name":"IL Патио","amenity":"restaurant"},"name":"IL Патио","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Jason's Deli":{"tags":{"name":"Jason's Deli","amenity":"restaurant"},"name":"Jason's Deli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Joe's Crab Shack":{"tags":{"name":"Joe's Crab Shack","amenity":"restaurant"},"name":"Joe's Crab Shack","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Jägerhof":{"tags":{"name":"Jägerhof","amenity":"restaurant"},"name":"Jägerhof","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kantine":{"tags":{"name":"Kantine","amenity":"restaurant"},"name":"Kantine","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kelsey's":{"tags":{"name":"Kelsey's","amenity":"restaurant"},"name":"Kelsey's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kirchenwirt":{"tags":{"name":"Kirchenwirt","amenity":"restaurant"},"name":"Kirchenwirt","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kreta":{"tags":{"name":"Kreta","amenity":"restaurant"},"name":"Kreta","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kreuz":{"tags":{"name":"Kreuz","amenity":"restaurant"},"name":"Kreuz","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Krone":{"tags":{"name":"Krone","amenity":"restaurant"},"name":"Krone","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kudu":{"tags":{"name":"Kudu","amenity":"restaurant"},"name":"Kudu","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/L'Escale":{"tags":{"name":"L'Escale","amenity":"restaurant"},"name":"L'Escale","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/L'Osteria":{"tags":{"name":"L'Osteria","amenity":"restaurant"},"name":"L'Osteria","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Bodega":{"tags":{"name":"La Bodega","amenity":"restaurant"},"name":"La Bodega","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Boucherie":{"tags":{"name":"La Boucherie","amenity":"restaurant"},"name":"La Boucherie","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Cantina":{"tags":{"name":"La Cantina","amenity":"restaurant"},"name":"La Cantina","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Casa":{"tags":{"name":"La Casa","amenity":"restaurant"},"name":"La Casa","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Casona":{"tags":{"name":"La Casona","amenity":"restaurant"},"name":"La Casona","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Dolce Vita":{"tags":{"name":"La Dolce Vita","amenity":"restaurant"},"name":"La Dolce Vita","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Fontana":{"tags":{"name":"La Fontana","amenity":"restaurant"},"name":"La Fontana","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Gondola":{"tags":{"name":"La Gondola","amenity":"restaurant"},"name":"La Gondola","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Hacienda":{"tags":{"name":"La Hacienda","amenity":"restaurant"},"name":"La Hacienda","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Pataterie":{"tags":{"name":"La Pataterie","amenity":"restaurant"},"name":"La Pataterie","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Pergola":{"tags":{"name":"La Pergola","amenity":"restaurant"},"name":"La Pergola","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Perla":{"tags":{"name":"La Perla","amenity":"restaurant"},"name":"La Perla","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Piazza":{"tags":{"name":"La Piazza","amenity":"restaurant"},"name":"La Piazza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Piazzetta":{"tags":{"name":"La Piazzetta","amenity":"restaurant"},"name":"La Piazzetta","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Place":{"tags":{"name":"La Place","amenity":"restaurant"},"name":"La Place","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Scala":{"tags":{"name":"La Scala","amenity":"restaurant"},"name":"La Scala","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Strada":{"tags":{"name":"La Strada","amenity":"restaurant"},"name":"La Strada","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Tagliatella":{"tags":{"name":"La Tagliatella","amenity":"restaurant"},"name":"La Tagliatella","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Tasca":{"tags":{"name":"La Tasca","amenity":"restaurant"},"name":"La Tasca","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Taverna":{"tags":{"name":"La Taverna","amenity":"restaurant"},"name":"La Taverna","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Terrasse":{"tags":{"name":"La Terrasse","amenity":"restaurant"},"name":"La Terrasse","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Terraza":{"tags":{"name":"La Terraza","amenity":"restaurant"},"name":"La Terraza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Terrazza":{"tags":{"name":"La Terrazza","amenity":"restaurant"},"name":"La Terrazza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Trattoria":{"tags":{"name":"La Trattoria","amenity":"restaurant"},"name":"La Trattoria","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Lamm":{"tags":{"name":"Lamm","amenity":"restaurant"},"name":"Lamm","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Linde":{"tags":{"name":"Linde","amenity":"restaurant"},"name":"Linde","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Lindenhof":{"tags":{"name":"Lindenhof","amenity":"restaurant"},"name":"Lindenhof","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Little Chef":{"tags":{"name":"Little Chef","amenity":"restaurant"},"name":"Little Chef","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Little Italy":{"tags":{"name":"Little Italy","amenity":"restaurant"},"name":"Little Italy","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Logan's Roadhouse":{"tags":{"name":"Logan's Roadhouse","amenity":"restaurant"},"name":"Logan's Roadhouse","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/LongHorn Steakhouse":{"tags":{"name":"LongHorn Steakhouse","amenity":"restaurant"},"name":"LongHorn Steakhouse","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Lotus":{"tags":{"name":"Lotus","amenity":"restaurant"},"name":"Lotus","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Léon de Bruxelles":{"tags":{"name":"Léon de Bruxelles","amenity":"restaurant"},"name":"Léon de Bruxelles","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Löwen":{"tags":{"name":"Löwen","amenity":"restaurant"},"name":"Löwen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/MK Restaurants":{"tags":{"name":"MK Restaurants","amenity":"restaurant"},"name":"MK Restaurants","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Maharaja":{"tags":{"name":"Maharaja","amenity":"restaurant"},"name":"Maharaja","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mamma Mia":{"tags":{"name":"Mamma Mia","amenity":"restaurant"},"name":"Mamma Mia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mandarin":{"tags":{"name":"Mandarin","amenity":"restaurant"},"name":"Mandarin","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mang Inasal":{"tags":{"name":"Mang Inasal","amenity":"restaurant"},"name":"Mang Inasal","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Marco Polo":{"tags":{"name":"Marco Polo","amenity":"restaurant"},"name":"Marco Polo","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Marco's Pizza":{"tags":{"name":"Marco's Pizza","amenity":"restaurant"},"name":"Marco's Pizza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/McAlister's Deli":{"tags":{"name":"McAlister's Deli","amenity":"restaurant"},"name":"McAlister's Deli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mediterraneo":{"tags":{"name":"Mediterraneo","amenity":"restaurant"},"name":"Mediterraneo","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mellow Mushroom":{"tags":{"name":"Mellow Mushroom","amenity":"restaurant"},"name":"Mellow Mushroom","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mensa":{"tags":{"name":"Mensa","amenity":"restaurant"},"name":"Mensa","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Milano":{"tags":{"name":"Milano","amenity":"restaurant"},"name":"Milano","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mimi's Cafe":{"tags":{"name":"Mimi's Cafe","amenity":"restaurant"},"name":"Mimi's Cafe","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Moe's Southwest Grill":{"tags":{"name":"Moe's Southwest Grill","amenity":"restaurant"},"name":"Moe's Southwest Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mykonos":{"tags":{"name":"Mykonos","amenity":"restaurant"},"name":"Mykonos","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mythos":{"tags":{"name":"Mythos","amenity":"restaurant"},"name":"Mythos","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Nando's":{"tags":{"name":"Nando's","amenity":"restaurant"},"name":"Nando's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Noodles & Company":{"tags":{"name":"Noodles & Company","amenity":"restaurant"},"name":"Noodles & Company","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/O'Charley's":{"tags":{"name":"O'Charley's","amenity":"restaurant"},"name":"O'Charley's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Oasis":{"tags":{"name":"Oasis","amenity":"restaurant"},"name":"Oasis","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ocean Basket":{"tags":{"name":"Ocean Basket","amenity":"restaurant"},"name":"Ocean Basket","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ochsen":{"tags":{"name":"Ochsen","amenity":"restaurant"},"name":"Ochsen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Old Chicago":{"tags":{"name":"Old Chicago","amenity":"restaurant"},"name":"Old Chicago","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Olive Garden":{"tags":{"name":"Olive Garden","amenity":"restaurant"},"name":"Olive Garden","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Olympia":{"tags":{"name":"Olympia","amenity":"restaurant"},"name":"Olympia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Osaka":{"tags":{"name":"Osaka","amenity":"restaurant"},"name":"Osaka","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Outback Steakhouse":{"tags":{"name":"Outback Steakhouse","amenity":"restaurant"},"name":"Outback Steakhouse","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/P.F. Chang's":{"tags":{"name":"P.F. Chang's","amenity":"restaurant"},"name":"P.F. Chang's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pancake House":{"tags":{"name":"Pancake House","amenity":"restaurant"},"name":"Pancake House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Panda":{"tags":{"name":"Panda","amenity":"restaurant"},"name":"Panda","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Panera Bread":{"tags":{"name":"Panera Bread","amenity":"restaurant"},"name":"Panera Bread","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Panorama":{"tags":{"name":"Panorama","amenity":"restaurant"},"name":"Panorama","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Parrilla":{"tags":{"name":"Parrilla","amenity":"restaurant"},"name":"Parrilla","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Peking":{"tags":{"name":"Peking","amenity":"restaurant"},"name":"Peking","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Perkins":{"tags":{"name":"Perkins","amenity":"restaurant"},"name":"Perkins","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pinocchio":{"tags":{"name":"Pinocchio","amenity":"restaurant"},"name":"Pinocchio","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Express":{"tags":{"name":"Pizza Express","amenity":"restaurant"},"name":"Pizza Express","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Factory":{"tags":{"name":"Pizza Factory","amenity":"restaurant"},"name":"Pizza Factory","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza House":{"tags":{"name":"Pizza House","amenity":"restaurant"},"name":"Pizza House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Hut":{"tags":{"name":"Pizza Hut","cuisine":"pizza","amenity":"restaurant"},"name":"Pizza Hut","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Ranch":{"tags":{"name":"Pizza Ranch","amenity":"restaurant"},"name":"Pizza Ranch","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Italia":{"tags":{"name":"Pizzeria Italia","amenity":"restaurant"},"name":"Pizzeria Italia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Milano":{"tags":{"name":"Pizzeria Milano","amenity":"restaurant"},"name":"Pizzeria Milano","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Napoli":{"tags":{"name":"Pizzeria Napoli","amenity":"restaurant"},"name":"Pizzeria Napoli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Roma":{"tags":{"name":"Pizzeria Roma","amenity":"restaurant"},"name":"Pizzeria Roma","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Venezia":{"tags":{"name":"Pizzeria Venezia","amenity":"restaurant"},"name":"Pizzeria Venezia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Poivre Rouge":{"tags":{"name":"Poivre Rouge","amenity":"restaurant"},"name":"Poivre Rouge","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pomodoro":{"tags":{"name":"Pomodoro","amenity":"restaurant"},"name":"Pomodoro","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Portofino":{"tags":{"name":"Portofino","amenity":"restaurant"},"name":"Portofino","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Poseidon":{"tags":{"name":"Poseidon","amenity":"restaurant"},"name":"Poseidon","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Prezzo":{"tags":{"name":"Prezzo","amenity":"restaurant"},"name":"Prezzo","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Qdoba Mexican Grill":{"tags":{"name":"Qdoba Mexican Grill","amenity":"restaurant"},"name":"Qdoba Mexican Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ratskeller":{"tags":{"name":"Ratskeller","amenity":"restaurant"},"name":"Ratskeller","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Red Lobster":{"tags":{"name":"Red Lobster","amenity":"restaurant"},"name":"Red Lobster","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Red Robin":{"tags":{"name":"Red Robin","amenity":"restaurant"},"name":"Red Robin","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Restaurante Universitário":{"tags":{"name":"Restaurante Universitário","amenity":"restaurant"},"name":"Restaurante Universitário","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rhodos":{"tags":{"name":"Rhodos","amenity":"restaurant"},"name":"Rhodos","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ristorante Del Arte":{"tags":{"name":"Ristorante Del Arte","amenity":"restaurant"},"name":"Ristorante Del Arte","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Roma":{"tags":{"name":"Roma","amenity":"restaurant"},"name":"Roma","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rose":{"tags":{"name":"Rose","amenity":"restaurant"},"name":"Rose","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Round Table Pizza":{"tags":{"name":"Round Table Pizza","amenity":"restaurant"},"name":"Round Table Pizza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ruby Tuesday":{"tags":{"name":"Ruby Tuesday","amenity":"restaurant"},"name":"Ruby Tuesday","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rössle":{"tags":{"name":"Rössle","amenity":"restaurant"},"name":"Rössle","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rössli":{"tags":{"name":"Rössli","amenity":"restaurant"},"name":"Rössli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Saigon":{"tags":{"name":"Saigon","amenity":"restaurant"},"name":"Saigon","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sakura":{"tags":{"name":"Sakura","amenity":"restaurant"},"name":"Sakura","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/San Marco":{"tags":{"name":"San Marco","amenity":"restaurant"},"name":"San Marco","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Santorini":{"tags":{"name":"Santorini","amenity":"restaurant"},"name":"Santorini","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Schwarzer Adler":{"tags":{"name":"Schwarzer Adler","amenity":"restaurant"},"name":"Schwarzer Adler","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Schützenhaus":{"tags":{"name":"Schützenhaus","amenity":"restaurant"},"name":"Schützenhaus","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shakey's":{"tags":{"name":"Shakey's","amenity":"restaurant"},"name":"Shakey's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shalimar":{"tags":{"name":"Shalimar","amenity":"restaurant"},"name":"Shalimar","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shanghai":{"tags":{"name":"Shanghai","amenity":"restaurant"},"name":"Shanghai","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shari's":{"tags":{"name":"Shari's","amenity":"restaurant"},"name":"Shari's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shoney's":{"tags":{"name":"Shoney's","amenity":"restaurant"},"name":"Shoney's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sizzler":{"tags":{"name":"Sizzler","amenity":"restaurant"},"name":"Sizzler","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sonne":{"tags":{"name":"Sonne","amenity":"restaurant"},"name":"Sonne","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sphinx":{"tags":{"name":"Sphinx","amenity":"restaurant"},"name":"Sphinx","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sportheim":{"tags":{"name":"Sportheim","amenity":"restaurant"},"name":"Sportheim","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Spur":{"tags":{"name":"Spur","amenity":"restaurant"},"name":"Spur","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Steak 'n Shake":{"tags":{"name":"Steak 'n Shake","cuisine":"burger","amenity":"restaurant"},"name":"Steak 'n Shake","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Steak House":{"tags":{"name":"Steak House","amenity":"restaurant"},"name":"Steak House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sternen":{"tags":{"name":"Sternen","amenity":"restaurant"},"name":"Sternen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sunset Grill":{"tags":{"name":"Sunset Grill","amenity":"restaurant"},"name":"Sunset Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sushi":{"tags":{"name":"Sushi","amenity":"restaurant"},"name":"Sushi","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sushi Bar":{"tags":{"name":"Sushi Bar","amenity":"restaurant"},"name":"Sushi Bar","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Swiss Chalet":{"tags":{"name":"Swiss Chalet","amenity":"restaurant"},"name":"Swiss Chalet","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Syrtaki":{"tags":{"name":"Syrtaki","amenity":"restaurant"},"name":"Syrtaki","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/TGI Friday's":{"tags":{"name":"TGI Friday's","amenity":"restaurant"},"name":"TGI Friday's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Taj Mahal":{"tags":{"name":"Taj Mahal","amenity":"restaurant"},"name":"Taj Mahal","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Taste of India":{"tags":{"name":"Taste of India","amenity":"restaurant"},"name":"Taste of India","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Taverna":{"tags":{"name":"Taverna","amenity":"restaurant"},"name":"Taverna","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Texas Roadhouse":{"tags":{"name":"Texas Roadhouse","amenity":"restaurant"},"name":"Texas Roadhouse","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/The Cheesecake Factory":{"tags":{"name":"The Cheesecake Factory","amenity":"restaurant"},"name":"The Cheesecake Factory","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Toby Carvery":{"tags":{"name":"Toby Carvery","amenity":"restaurant"},"name":"Toby Carvery","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Tony Roma's":{"tags":{"name":"Tony Roma's","amenity":"restaurant"},"name":"Tony Roma's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Toscana":{"tags":{"name":"Toscana","amenity":"restaurant"},"name":"Toscana","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Trattoria":{"tags":{"name":"Trattoria","amenity":"restaurant"},"name":"Trattoria","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Traube":{"tags":{"name":"Traube","amenity":"restaurant"},"name":"Traube","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Vapiano":{"tags":{"name":"Vapiano","amenity":"restaurant"},"name":"Vapiano","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Venezia":{"tags":{"name":"Venezia","amenity":"restaurant"},"name":"Venezia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Village Inn":{"tags":{"name":"Village Inn","amenity":"restaurant"},"name":"Village Inn","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Vips":{"tags":{"name":"Vips","amenity":"restaurant"},"name":"Vips","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Waffle House":{"tags":{"name":"Waffle House","amenity":"restaurant"},"name":"Waffle House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Wagamama":{"tags":{"name":"Wagamama","amenity":"restaurant"},"name":"Wagamama","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Waldschänke":{"tags":{"name":"Waldschänke","amenity":"restaurant"},"name":"Waldschänke","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Warung":{"tags":{"name":"Warung","amenity":"restaurant"},"name":"Warung","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Wasabi":{"tags":{"name":"Wasabi","amenity":"restaurant"},"name":"Wasabi","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zizzi":{"tags":{"name":"Zizzi","amenity":"restaurant"},"name":"Zizzi","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zorbas":{"tags":{"name":"Zorbas","amenity":"restaurant"},"name":"Zorbas","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zum Hirschen":{"tags":{"name":"Zum Hirschen","amenity":"restaurant"},"name":"Zum Hirschen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zum Löwen":{"tags":{"name":"Zum Löwen","amenity":"restaurant"},"name":"Zum Löwen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Krone":{"tags":{"name":"Zur Krone","amenity":"restaurant"},"name":"Zur Krone","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Linde":{"tags":{"name":"Zur Linde","amenity":"restaurant"},"name":"Zur Linde","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Post":{"tags":{"name":"Zur Post","amenity":"restaurant"},"name":"Zur Post","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Sonne":{"tags":{"name":"Zur Sonne","amenity":"restaurant"},"name":"Zur Sonne","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Евразия":{"tags":{"name":"Евразия","amenity":"restaurant"},"name":"Евразия","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ресторан":{"tags":{"name":"Ресторан","amenity":"restaurant"},"name":"Ресторан","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Тануки":{"tags":{"name":"Тануки","amenity":"restaurant"},"name":"Тануки","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Якитория":{"tags":{"name":"Якитория","amenity":"restaurant"},"name":"Якитория","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/رستوران":{"tags":{"name":"رستوران","amenity":"restaurant"},"name":"رستوران","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/مطعم":{"tags":{"name":"مطعم","amenity":"restaurant"},"name":"مطعم","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/はま寿司":{"tags":{"name":"はま寿司","amenity":"restaurant"},"name":"はま寿司","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/びっくりドンキー":{"tags":{"name":"びっくりドンキー","amenity":"restaurant"},"name":"びっくりドンキー","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/やよい軒":{"tags":{"name":"やよい軒","amenity":"restaurant"},"name":"やよい軒","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ガスト":{"tags":{"name":"ガスト","name:en":"Gusto","amenity":"restaurant"},"name":"ガスト","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ココス":{"tags":{"name":"ココス","amenity":"restaurant"},"name":"ココス","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/サイゼリア":{"tags":{"name":"サイゼリア","amenity":"restaurant"},"name":"サイゼリア","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/サイゼリヤ":{"tags":{"name":"サイゼリヤ","amenity":"restaurant"},"name":"サイゼリヤ","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ジョイフル":{"tags":{"name":"ジョイフル","amenity":"restaurant"},"name":"ジョイフル","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ジョナサン":{"tags":{"name":"ジョナサン","amenity":"restaurant"},"name":"ジョナサン","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ジョリーパスタ":{"tags":{"name":"ジョリーパスタ","amenity":"restaurant"},"name":"ジョリーパスタ","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/デニーズ":{"tags":{"name":"デニーズ","amenity":"restaurant"},"name":"デニーズ","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/バーミヤン":{"tags":{"name":"バーミヤン","amenity":"restaurant"},"name":"バーミヤン","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ロイヤルホスト":{"tags":{"name":"ロイヤルホスト","amenity":"restaurant"},"name":"ロイヤルホスト","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/丸亀製麺":{"tags":{"name":"丸亀製麺","amenity":"restaurant"},"name":"丸亀製麺","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/八方雲集":{"tags":{"name":"八方雲集","amenity":"restaurant"},"name":"八方雲集","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/夢庵":{"tags":{"name":"夢庵","amenity":"restaurant"},"name":"夢庵","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/大戸屋":{"tags":{"name":"大戸屋","amenity":"restaurant"},"name":"大戸屋","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/大阪王将":{"tags":{"name":"大阪王将","amenity":"restaurant"},"name":"大阪王将","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/天下一品":{"tags":{"name":"天下一品","amenity":"restaurant"},"name":"天下一品","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/安楽亭":{"tags":{"name":"安楽亭","amenity":"restaurant"},"name":"安楽亭","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/牛角":{"tags":{"name":"牛角","amenity":"restaurant"},"name":"牛角","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/食堂":{"tags":{"name":"食堂","amenity":"restaurant"},"name":"食堂","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/餃子の王将":{"tags":{"name":"餃子の王将","amenity":"restaurant"},"name":"餃子の王将","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/바다횟집 (Bada Fish Restaurant)":{"tags":{"name":"바다횟집 (Bada Fish Restaurant)","amenity":"restaurant"},"name":"바다횟집 (Bada Fish Restaurant)","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/school/Adolfo Lopez Mateos":{"tags":{"name":"Adolfo Lopez Mateos","amenity":"school"},"name":"Adolfo Lopez Mateos","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Agustin Ya�ez":{"tags":{"name":"Agustin Ya�ez","amenity":"school"},"name":"Agustin Ya�ez","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Albert-Schweitzer-Schule":{"tags":{"name":"Albert-Schweitzer-Schule","amenity":"school"},"name":"Albert-Schweitzer-Schule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Amado Nervo":{"tags":{"name":"Amado Nervo","amenity":"school"},"name":"Amado Nervo","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Astrid-Lindgren-Schule":{"tags":{"name":"Astrid-Lindgren-Schule","amenity":"school"},"name":"Astrid-Lindgren-Schule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Benito Juarez":{"tags":{"name":"Benito Juarez","amenity":"school"},"name":"Benito Juarez","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Brown School":{"tags":{"name":"Brown School","amenity":"school"},"name":"Brown School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/CEM":{"tags":{"name":"CEM","amenity":"school"},"name":"CEM","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Center School":{"tags":{"name":"Center School","amenity":"school"},"name":"Center School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Central Elementary School":{"tags":{"name":"Central Elementary School","amenity":"school"},"name":"Central Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Central High School":{"tags":{"name":"Central High School","amenity":"school"},"name":"Central High School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Central School":{"tags":{"name":"Central School","amenity":"school"},"name":"Central School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Colegio San José":{"tags":{"name":"Colegio San José","amenity":"school"},"name":"Colegio San José","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Collège Jean Moulin":{"tags":{"name":"Collège Jean Moulin","amenity":"school"},"name":"Collège Jean Moulin","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Collège privé Saint-Joseph":{"tags":{"name":"Collège privé Saint-Joseph","amenity":"school"},"name":"Collège privé Saint-Joseph","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Cuauhtemoc":{"tags":{"name":"Cuauhtemoc","amenity":"school"},"name":"Cuauhtemoc","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Curso Comunitario":{"tags":{"name":"Curso Comunitario","amenity":"school"},"name":"Curso Comunitario","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Cursos Comunitarios":{"tags":{"name":"Cursos Comunitarios","amenity":"school"},"name":"Cursos Comunitarios","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/EPP":{"tags":{"name":"EPP","amenity":"school"},"name":"EPP","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Emiliano Zapata":{"tags":{"name":"Emiliano Zapata","amenity":"school"},"name":"Emiliano Zapata","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Escola Estadual":{"tags":{"name":"Escola Estadual","amenity":"school"},"name":"Escola Estadual","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Escola Municipal":{"tags":{"name":"Escola Municipal","amenity":"school"},"name":"Escola Municipal","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Fairview Elementary School":{"tags":{"name":"Fairview Elementary School","amenity":"school"},"name":"Fairview Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Fairview School":{"tags":{"name":"Fairview School","amenity":"school"},"name":"Fairview School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Francisco I Madero":{"tags":{"name":"Francisco I Madero","amenity":"school"},"name":"Francisco I Madero","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Francisco I. Madero":{"tags":{"name":"Francisco I. Madero","amenity":"school"},"name":"Francisco I. Madero","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Francisco Villa":{"tags":{"name":"Francisco Villa","amenity":"school"},"name":"Francisco Villa","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Franklin Elementary School":{"tags":{"name":"Franklin Elementary School","amenity":"school"},"name":"Franklin Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Franklin School":{"tags":{"name":"Franklin School","amenity":"school"},"name":"Franklin School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Garfield Elementary School":{"tags":{"name":"Garfield Elementary School","amenity":"school"},"name":"Garfield Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Garfield School":{"tags":{"name":"Garfield School","amenity":"school"},"name":"Garfield School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Gimnazjum nr 1":{"tags":{"name":"Gimnazjum nr 1","amenity":"school"},"name":"Gimnazjum nr 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Government School":{"tags":{"name":"Government School","amenity":"school"},"name":"Government School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Gregorio Torres Quintero":{"tags":{"name":"Gregorio Torres Quintero","amenity":"school"},"name":"Gregorio Torres Quintero","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Groupe Scolaire":{"tags":{"name":"Groupe Scolaire","amenity":"school"},"name":"Groupe Scolaire","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Guadalupe Victoria":{"tags":{"name":"Guadalupe Victoria","amenity":"school"},"name":"Guadalupe Victoria","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Highland School":{"tags":{"name":"Highland School","amenity":"school"},"name":"Highland School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Hillcrest Elementary School":{"tags":{"name":"Hillcrest Elementary School","amenity":"school"},"name":"Hillcrest Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Holy Cross School":{"tags":{"name":"Holy Cross School","amenity":"school"},"name":"Holy Cross School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Holy Family School":{"tags":{"name":"Holy Family School","amenity":"school"},"name":"Holy Family School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Holy Trinity School":{"tags":{"name":"Holy Trinity School","amenity":"school"},"name":"Holy Trinity School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ignacio Allende":{"tags":{"name":"Ignacio Allende","amenity":"school"},"name":"Ignacio Allende","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ignacio Zaragoza":{"tags":{"name":"Ignacio Zaragoza","amenity":"school"},"name":"Ignacio Zaragoza","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Immaculate Conception School":{"tags":{"name":"Immaculate Conception School","amenity":"school"},"name":"Immaculate Conception School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jackson Elementary School":{"tags":{"name":"Jackson Elementary School","amenity":"school"},"name":"Jackson Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jackson School":{"tags":{"name":"Jackson School","amenity":"school"},"name":"Jackson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jefferson Elementary School":{"tags":{"name":"Jefferson Elementary School","amenity":"school"},"name":"Jefferson Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jefferson School":{"tags":{"name":"Jefferson School","amenity":"school"},"name":"Jefferson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jose Clemente Orozco":{"tags":{"name":"Jose Clemente Orozco","amenity":"school"},"name":"Jose Clemente Orozco","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jose Ma Morelos Y Pavon":{"tags":{"name":"Jose Ma Morelos Y Pavon","amenity":"school"},"name":"Jose Ma Morelos Y Pavon","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Jose Vasconcelos":{"tags":{"name":"Jose Vasconcelos","amenity":"school"},"name":"Jose Vasconcelos","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Josefa Ortiz De Dominguez":{"tags":{"name":"Josefa Ortiz De Dominguez","amenity":"school"},"name":"Josefa Ortiz De Dominguez","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Juan Escutia":{"tags":{"name":"Juan Escutia","amenity":"school"},"name":"Juan Escutia","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Justo Sierra":{"tags":{"name":"Justo Sierra","amenity":"school"},"name":"Justo Sierra","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Kumon":{"tags":{"name":"Kumon","amenity":"school"},"name":"Kumon","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Lazaro Cardenas":{"tags":{"name":"Lazaro Cardenas","amenity":"school"},"name":"Lazaro Cardenas","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Lazaro Cardenas Del Rio":{"tags":{"name":"Lazaro Cardenas Del Rio","amenity":"school"},"name":"Lazaro Cardenas Del Rio","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Leona Vicario":{"tags":{"name":"Leona Vicario","amenity":"school"},"name":"Leona Vicario","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Liberty Elementary School":{"tags":{"name":"Liberty Elementary School","amenity":"school"},"name":"Liberty Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Liberty School":{"tags":{"name":"Liberty School","amenity":"school"},"name":"Liberty School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Lincoln Elementary School":{"tags":{"name":"Lincoln Elementary School","amenity":"school"},"name":"Lincoln Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Lincoln School":{"tags":{"name":"Lincoln School","amenity":"school"},"name":"Lincoln School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Longfellow Elementary School":{"tags":{"name":"Longfellow Elementary School","amenity":"school"},"name":"Longfellow Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Longfellow School":{"tags":{"name":"Longfellow School","amenity":"school"},"name":"Longfellow School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Madison Elementary School":{"tags":{"name":"Madison Elementary School","amenity":"school"},"name":"Madison Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Manuel Lopez Cotilla":{"tags":{"name":"Manuel Lopez Cotilla","amenity":"school"},"name":"Manuel Lopez Cotilla","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Maple Grove School":{"tags":{"name":"Maple Grove School","amenity":"school"},"name":"Maple Grove School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/McKinley Elementary School":{"tags":{"name":"McKinley Elementary School","amenity":"school"},"name":"McKinley Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/McKinley School":{"tags":{"name":"McKinley School","amenity":"school"},"name":"McKinley School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Miguel Hidalgo":{"tags":{"name":"Miguel Hidalgo","amenity":"school"},"name":"Miguel Hidalgo","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Miguel Hidalgo Y Costilla":{"tags":{"name":"Miguel Hidalgo Y Costilla","amenity":"school"},"name":"Miguel Hidalgo Y Costilla","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Miller School":{"tags":{"name":"Miller School","amenity":"school"},"name":"Miller School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Mount Pleasant School":{"tags":{"name":"Mount Pleasant School","amenity":"school"},"name":"Mount Pleasant School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Mount Zion School":{"tags":{"name":"Mount Zion School","amenity":"school"},"name":"Mount Zion School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Mountain View Elementary School":{"tags":{"name":"Mountain View Elementary School","amenity":"school"},"name":"Mountain View Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/New Hope School":{"tags":{"name":"New Hope School","amenity":"school"},"name":"New Hope School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Nicolas Bravo":{"tags":{"name":"Nicolas Bravo","amenity":"school"},"name":"Nicolas Bravo","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ni�os Heroes":{"tags":{"name":"Ni�os Heroes","amenity":"school"},"name":"Ni�os Heroes","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Nombre En Tramite":{"tags":{"name":"Nombre En Tramite","amenity":"school"},"name":"Nombre En Tramite","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/North Elementary School":{"tags":{"name":"North Elementary School","amenity":"school"},"name":"North Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Oak Grove School":{"tags":{"name":"Oak Grove School","amenity":"school"},"name":"Oak Grove School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pedro Moreno":{"tags":{"name":"Pedro Moreno","amenity":"school"},"name":"Pedro Moreno","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pestalozzischule":{"tags":{"name":"Pestalozzischule","amenity":"school"},"name":"Pestalozzischule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pine Grove School":{"tags":{"name":"Pine Grove School","amenity":"school"},"name":"Pine Grove School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pleasant Hill School":{"tags":{"name":"Pleasant Hill School","amenity":"school"},"name":"Pleasant Hill School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pleasant Valley School":{"tags":{"name":"Pleasant Valley School","amenity":"school"},"name":"Pleasant Valley School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pleasant View School":{"tags":{"name":"Pleasant View School","amenity":"school"},"name":"Pleasant View School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Primaria Comunitaria":{"tags":{"name":"Primaria Comunitaria","amenity":"school"},"name":"Primaria Comunitaria","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ramon Corona":{"tags":{"name":"Ramon Corona","amenity":"school"},"name":"Ramon Corona","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ricardo Flores Magon":{"tags":{"name":"Ricardo Flores Magon","amenity":"school"},"name":"Ricardo Flores Magon","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Riverside School":{"tags":{"name":"Riverside School","amenity":"school"},"name":"Riverside School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Roosevelt Elementary School":{"tags":{"name":"Roosevelt Elementary School","amenity":"school"},"name":"Roosevelt Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Roosevelt School":{"tags":{"name":"Roosevelt School","amenity":"school"},"name":"Roosevelt School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/SD":{"tags":{"name":"SD","amenity":"school"},"name":"SD","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/SDN":{"tags":{"name":"SDN","amenity":"school"},"name":"SDN","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Sacred Heart School":{"tags":{"name":"Sacred Heart School","amenity":"school"},"name":"Sacred Heart School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Francis School":{"tags":{"name":"Saint Francis School","amenity":"school"},"name":"Saint Francis School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint James School":{"tags":{"name":"Saint James School","amenity":"school"},"name":"Saint James School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Johns School":{"tags":{"name":"Saint Johns School","amenity":"school"},"name":"Saint Johns School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Joseph School":{"tags":{"name":"Saint Joseph School","amenity":"school"},"name":"Saint Joseph School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Josephs School":{"tags":{"name":"Saint Josephs School","amenity":"school"},"name":"Saint Josephs School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Kizito Primary School":{"tags":{"name":"Saint Kizito Primary School","amenity":"school"},"name":"Saint Kizito Primary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Mary School":{"tags":{"name":"Saint Mary School","amenity":"school"},"name":"Saint Mary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Marys School":{"tags":{"name":"Saint Marys School","amenity":"school"},"name":"Saint Marys School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Patricks School":{"tags":{"name":"Saint Patricks School","amenity":"school"},"name":"Saint Patricks School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Paul School":{"tags":{"name":"Saint Paul School","amenity":"school"},"name":"Saint Paul School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Pauls School":{"tags":{"name":"Saint Pauls School","amenity":"school"},"name":"Saint Pauls School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Saint Peters School":{"tags":{"name":"Saint Peters School","amenity":"school"},"name":"Saint Peters School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Schillerschule":{"tags":{"name":"Schillerschule","amenity":"school"},"name":"Schillerschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/School Number 1":{"tags":{"name":"School Number 1","amenity":"school"},"name":"School Number 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/School Number 2":{"tags":{"name":"School Number 2","amenity":"school"},"name":"School Number 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/School Number 3":{"tags":{"name":"School Number 3","amenity":"school"},"name":"School Number 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/School Number 4":{"tags":{"name":"School Number 4","amenity":"school"},"name":"School Number 4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Smith School":{"tags":{"name":"Smith School","amenity":"school"},"name":"Smith School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/South Elementary School":{"tags":{"name":"South Elementary School","amenity":"school"},"name":"South Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Sunnyside School":{"tags":{"name":"Sunnyside School","amenity":"school"},"name":"Sunnyside School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Szkoła Podstawowa nr 1":{"tags":{"name":"Szkoła Podstawowa nr 1","amenity":"school"},"name":"Szkoła Podstawowa nr 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Szkoła Podstawowa nr 2":{"tags":{"name":"Szkoła Podstawowa nr 2","amenity":"school"},"name":"Szkoła Podstawowa nr 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Szkoła Podstawowa nr 3":{"tags":{"name":"Szkoła Podstawowa nr 3","amenity":"school"},"name":"Szkoła Podstawowa nr 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Trinity School":{"tags":{"name":"Trinity School","amenity":"school"},"name":"Trinity School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/UNIDAD EDUCATIVA":{"tags":{"name":"UNIDAD EDUCATIVA","amenity":"school"},"name":"UNIDAD EDUCATIVA","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Union School":{"tags":{"name":"Union School","amenity":"school"},"name":"Union School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Valentin Gomez Farias":{"tags":{"name":"Valentin Gomez Farias","amenity":"school"},"name":"Valentin Gomez Farias","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Venustiano Carranza":{"tags":{"name":"Venustiano Carranza","amenity":"school"},"name":"Venustiano Carranza","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Vicente Guerrero":{"tags":{"name":"Vicente Guerrero","amenity":"school"},"name":"Vicente Guerrero","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Volkshochschule":{"tags":{"name":"Volkshochschule","amenity":"school"},"name":"Volkshochschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Volksschule":{"tags":{"name":"Volksschule","amenity":"school"},"name":"Volksschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Washington Elementary School":{"tags":{"name":"Washington Elementary School","amenity":"school"},"name":"Washington Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Washington School":{"tags":{"name":"Washington School","amenity":"school"},"name":"Washington School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/West Elementary School":{"tags":{"name":"West Elementary School","amenity":"school"},"name":"West Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/White School":{"tags":{"name":"White School","amenity":"school"},"name":"White School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Wilson Elementary School":{"tags":{"name":"Wilson Elementary School","amenity":"school"},"name":"Wilson Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Wilson School":{"tags":{"name":"Wilson School","amenity":"school"},"name":"Wilson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Általános iskola":{"tags":{"name":"Általános iskola","amenity":"school"},"name":"Általános iskola","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École Jules Ferry":{"tags":{"name":"École Jules Ferry","amenity":"school"},"name":"École Jules Ferry","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École Notre-Dame":{"tags":{"name":"École Notre-Dame","amenity":"school"},"name":"École Notre-Dame","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École Saint-Joseph":{"tags":{"name":"École Saint-Joseph","amenity":"school"},"name":"École Saint-Joseph","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École primaire Jean Jaurès":{"tags":{"name":"École primaire Jean Jaurès","amenity":"school"},"name":"École primaire Jean Jaurès","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École primaire Jules Ferry":{"tags":{"name":"École primaire Jules Ferry","amenity":"school"},"name":"École primaire Jules Ferry","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École primaire privée Notre-Dame":{"tags":{"name":"École primaire privée Notre-Dame","amenity":"school"},"name":"École primaire privée Notre-Dame","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École primaire privée Saint-Joseph":{"tags":{"name":"École primaire privée Saint-Joseph","amenity":"school"},"name":"École primaire privée Saint-Joseph","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École primaire privée Sainte-Marie":{"tags":{"name":"École primaire privée Sainte-Marie","amenity":"school"},"name":"École primaire privée Sainte-Marie","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/École élémentaire Jules Ferry":{"tags":{"name":"École élémentaire Jules Ferry","amenity":"school"},"name":"École élémentaire Jules Ferry","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Școala Generală":{"tags":{"name":"Școala Generală","amenity":"school"},"name":"Școala Generală","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Școală":{"tags":{"name":"Școală","amenity":"school"},"name":"Școală","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Вечерняя школа":{"tags":{"name":"Вечерняя школа","amenity":"school"},"name":"Вечерняя школа","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Гимназия №1":{"tags":{"name":"Гимназия №1","amenity":"school"},"name":"Гимназия №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Средняя школа №1":{"tags":{"name":"Средняя школа №1","amenity":"school"},"name":"Средняя школа №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Средняя школа №2":{"tags":{"name":"Средняя школа №2","amenity":"school"},"name":"Средняя школа №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Средняя школа №3":{"tags":{"name":"Средняя школа №3","amenity":"school"},"name":"Средняя школа №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 1":{"tags":{"name":"Школа № 1","amenity":"school"},"name":"Школа № 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 2":{"tags":{"name":"Школа № 2","amenity":"school"},"name":"Школа № 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 3":{"tags":{"name":"Школа № 3","amenity":"school"},"name":"Школа № 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 4":{"tags":{"name":"Школа № 4","amenity":"school"},"name":"Школа № 4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 5":{"tags":{"name":"Школа № 5","amenity":"school"},"name":"Школа № 5","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №1":{"tags":{"name":"Школа №1","amenity":"school"},"name":"Школа №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №10":{"tags":{"name":"Школа №10","amenity":"school"},"name":"Школа №10","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №11":{"tags":{"name":"Школа №11","amenity":"school"},"name":"Школа №11","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №12":{"tags":{"name":"Школа №12","amenity":"school"},"name":"Школа №12","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №13":{"tags":{"name":"Школа №13","amenity":"school"},"name":"Школа №13","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №14":{"tags":{"name":"Школа №14","amenity":"school"},"name":"Школа №14","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №15":{"tags":{"name":"Школа №15","amenity":"school"},"name":"Школа №15","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №16":{"tags":{"name":"Школа №16","amenity":"school"},"name":"Школа №16","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №17":{"tags":{"name":"Школа №17","amenity":"school"},"name":"Школа №17","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №18":{"tags":{"name":"Школа №18","amenity":"school"},"name":"Школа №18","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №19":{"tags":{"name":"Школа №19","amenity":"school"},"name":"Школа №19","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №2":{"tags":{"name":"Школа №2","amenity":"school"},"name":"Школа №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №20":{"tags":{"name":"Школа №20","amenity":"school"},"name":"Школа №20","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №21":{"tags":{"name":"Школа №21","amenity":"school"},"name":"Школа №21","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №22":{"tags":{"name":"Школа №22","amenity":"school"},"name":"Школа №22","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №23":{"tags":{"name":"Школа №23","amenity":"school"},"name":"Школа №23","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №24":{"tags":{"name":"Школа №24","amenity":"school"},"name":"Школа №24","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №25":{"tags":{"name":"Школа №25","amenity":"school"},"name":"Школа №25","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №26":{"tags":{"name":"Школа №26","amenity":"school"},"name":"Школа №26","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №27":{"tags":{"name":"Школа №27","amenity":"school"},"name":"Школа №27","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №28":{"tags":{"name":"Школа №28","amenity":"school"},"name":"Школа №28","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №3":{"tags":{"name":"Школа №3","amenity":"school"},"name":"Школа №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №31":{"tags":{"name":"Школа №31","amenity":"school"},"name":"Школа №31","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №35":{"tags":{"name":"Школа №35","amenity":"school"},"name":"Школа №35","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №4":{"tags":{"name":"Школа №4","amenity":"school"},"name":"Школа №4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №5":{"tags":{"name":"Школа №5","amenity":"school"},"name":"Школа №5","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №6":{"tags":{"name":"Школа №6","amenity":"school"},"name":"Школа №6","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №7":{"tags":{"name":"Школа №7","amenity":"school"},"name":"Школа №7","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №8":{"tags":{"name":"Школа №8","amenity":"school"},"name":"Школа №8","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №9":{"tags":{"name":"Школа №9","amenity":"school"},"name":"Школа №9","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/مدرسة":{"tags":{"name":"مدرسة","amenity":"school"},"name":"مدرسة","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/مدرسه":{"tags":{"name":"مدرسه","amenity":"school"},"name":"مدرسه","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/市立南中学校":{"tags":{"name":"市立南中学校","amenity":"school"},"name":"市立南中学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/市立南小学校":{"tags":{"name":"市立南小学校","amenity":"school"},"name":"市立南小学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/市立東中学校":{"tags":{"name":"市立東中学校","amenity":"school"},"name":"市立東中学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/social_facility/Safe Haven":{"tags":{"name":"Safe Haven","amenity":"social_facility"},"name":"Safe Haven","icon":"poi-social-facility","geometry":["point","area"],"fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"suggestion":true},"amenity/social_facility/Детский дом":{"tags":{"name":"Детский дом","amenity":"social_facility"},"name":"Детский дом","icon":"poi-social-facility","geometry":["point","area"],"fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"suggestion":true},"amenity/social_facility/Социальный участковый":{"tags":{"name":"Социальный участковый","amenity":"social_facility"},"name":"Социальный участковый","icon":"poi-social-facility","geometry":["point","area"],"fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"suggestion":true},"amenity/theatre/Amfiteatr":{"tags":{"name":"Amfiteatr","amenity":"theatre"},"name":"Amfiteatr","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Amphitheater":{"tags":{"name":"Amphitheater","amenity":"theatre"},"name":"Amphitheater","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Amphitheatre":{"tags":{"name":"Amphitheatre","amenity":"theatre"},"name":"Amphitheatre","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Anfiteatro":{"tags":{"name":"Anfiteatro","amenity":"theatre"},"name":"Anfiteatro","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Freilichtbühne":{"tags":{"name":"Freilichtbühne","amenity":"theatre"},"name":"Freilichtbühne","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Teatro Comunale":{"tags":{"name":"Teatro Comunale","amenity":"theatre"},"name":"Teatro Comunale","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Teatro Municipal":{"tags":{"name":"Teatro Municipal","amenity":"theatre"},"name":"Teatro Municipal","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/veterinary/Clinica Veterinaria":{"tags":{"name":"Clinica Veterinaria","amenity":"veterinary"},"name":"Clinica Veterinaria","icon":"veterinary","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"amenity/veterinary/Veterinaria":{"tags":{"name":"Veterinaria","amenity":"veterinary"},"name":"Veterinaria","icon":"veterinary","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"leisure/fitness_centre/LA Fitness":{"tags":{"name":"LA Fitness","leisure":"fitness_centre"},"name":"LA Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/fitness_centre/Planet Fitness":{"tags":{"name":"Planet Fitness","leisure":"fitness_centre"},"name":"Planet Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/fitness_centre/Snap Fitness":{"tags":{"name":"Snap Fitness","leisure":"fitness_centre"},"name":"Snap Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/playground/Çocuk Parkı":{"tags":{"name":"Çocuk Parkı","leisure":"playground"},"name":"Çocuk Parkı","icon":"playground","geometry":["point","area"],"suggestion":true},"leisure/playground/놀이터":{"tags":{"name":"놀이터","leisure":"playground"},"name":"놀이터","icon":"playground","geometry":["point","area"],"suggestion":true},"leisure/sports_centre/Anytime Fitness":{"tags":{"name":"Anytime Fitness","leisure":"sports_centre"},"name":"Anytime Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Complejo Municipal de Deportes":{"tags":{"name":"Complejo Municipal de Deportes","leisure":"sports_centre"},"name":"Complejo Municipal de Deportes","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Complexe Sportif":{"tags":{"name":"Complexe Sportif","leisure":"sports_centre"},"name":"Complexe Sportif","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Curves":{"tags":{"name":"Curves","leisure":"sports_centre"},"name":"Curves","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Fitness First":{"tags":{"name":"Fitness First","leisure":"sports_centre"},"name":"Fitness First","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Gold's Gym":{"tags":{"name":"Gold's Gym","leisure":"sports_centre"},"name":"Gold's Gym","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Kieser Training":{"tags":{"name":"Kieser Training","leisure":"sports_centre"},"name":"Kieser Training","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Life Time Fitness":{"tags":{"name":"Life Time Fitness","leisure":"sports_centre"},"name":"Life Time Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/McFit":{"tags":{"name":"McFit","leisure":"sports_centre"},"name":"McFit","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Mrs. Sporty":{"tags":{"name":"Mrs. Sporty","leisure":"sports_centre"},"name":"Mrs. Sporty","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Orlik":{"tags":{"name":"Orlik","leisure":"sports_centre"},"name":"Orlik","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Pabellón Municipal de Deportes":{"tags":{"name":"Pabellón Municipal de Deportes","leisure":"sports_centre"},"name":"Pabellón Municipal de Deportes","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Palestra Comunale":{"tags":{"name":"Palestra Comunale","leisure":"sports_centre"},"name":"Palestra Comunale","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Polideportivo":{"tags":{"name":"Polideportivo","leisure":"sports_centre"},"name":"Polideportivo","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Salle Omnisport":{"tags":{"name":"Salle Omnisport","leisure":"sports_centre"},"name":"Salle Omnisport","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Virgin Active":{"tags":{"name":"Virgin Active","leisure":"sports_centre"},"name":"Virgin Active","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/YMCA":{"tags":{"name":"YMCA","leisure":"sports_centre"},"name":"YMCA","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/ДЮСШ":{"tags":{"name":"ДЮСШ","leisure":"sports_centre"},"name":"ДЮСШ","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/Ледовый дворец":{"tags":{"name":"Ледовый дворец","leisure":"sports_centre"},"name":"Ледовый дворец","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/sports_centre/体育館":{"tags":{"name":"体育館","leisure":"sports_centre"},"name":"体育館","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/swimming_pool/Schwimmerbecken":{"tags":{"name":"Schwimmerbecken","leisure":"swimming_pool"},"name":"Schwimmerbecken","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"leisure/swimming_pool/Yüzme Havuzu":{"tags":{"name":"Yüzme Havuzu","leisure":"swimming_pool"},"name":"Yüzme Havuzu","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"leisure/swimming_pool/プール":{"tags":{"name":"プール","leisure":"swimming_pool"},"name":"プール","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"leisure/swimming_pool/游泳池":{"tags":{"name":"游泳池","leisure":"swimming_pool"},"name":"游泳池","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"man_made/windmill/De Hoop":{"tags":{"name":"De Hoop","man_made":"windmill"},"name":"De Hoop","icon":"poi-windmill","geometry":["point","area"],"fields":["building_area"],"suggestion":true},"shop/alcohol/Alko":{"tags":{"name":"Alko","shop":"alcohol"},"name":"Alko","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/BC Liquor Store":{"tags":{"name":"BC Liquor Store","shop":"alcohol"},"name":"BC Liquor Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Beer Store":{"tags":{"name":"Beer Store","shop":"alcohol"},"name":"Beer Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Dan Murphy's":{"tags":{"name":"Dan Murphy's","shop":"alcohol"},"name":"Dan Murphy's","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Liquor Depot":{"tags":{"name":"Liquor Depot","shop":"alcohol"},"name":"Liquor Depot","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Liquor Store":{"tags":{"name":"Liquor Store","shop":"alcohol"},"name":"Liquor Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Liquorland":{"tags":{"name":"Liquorland","shop":"alcohol"},"name":"Liquorland","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Mitra":{"tags":{"name":"Mitra","shop":"alcohol"},"name":"Mitra","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Vinmonopolet":{"tags":{"name":"Vinmonopolet","shop":"alcohol"},"name":"Vinmonopolet","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Алкомаркет":{"tags":{"name":"Алкомаркет","shop":"alcohol"},"name":"Алкомаркет","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Ароматный мир":{"tags":{"name":"Ароматный мир","shop":"alcohol"},"name":"Ароматный мир","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Бристоль":{"tags":{"name":"Бристоль","shop":"alcohol"},"name":"Бристоль","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Градус":{"tags":{"name":"Градус","shop":"alcohol"},"name":"Градус","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Живое пиво":{"tags":{"name":"Живое пиво","shop":"alcohol"},"name":"Живое пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Красное & Белое":{"tags":{"name":"Красное & Белое","shop":"alcohol"},"name":"Красное & Белое","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Норман":{"tags":{"name":"Норман","shop":"alcohol"},"name":"Норман","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Отдохни":{"tags":{"name":"Отдохни","shop":"alcohol"},"name":"Отдохни","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Пиво":{"tags":{"name":"Пиво","shop":"alcohol"},"name":"Пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Разливное пиво":{"tags":{"name":"Разливное пиво","shop":"alcohol"},"name":"Разливное пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/baby_goods/Aubert":{"tags":{"name":"Aubert","shop":"baby_goods"},"name":"Aubert","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/baby_goods/Babies R Us":{"tags":{"name":"Babies R Us","shop":"baby_goods"},"name":"Babies R Us","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/baby_goods/BabyOne":{"tags":{"name":"BabyOne","shop":"baby_goods"},"name":"BabyOne","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/AILI":{"tags":{"name":"AILI","shop":"bakery"},"name":"AILI","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Anker":{"tags":{"name":"Anker","shop":"bakery"},"name":"Anker","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Awiteks":{"tags":{"name":"Awiteks","shop":"bakery"},"name":"Awiteks","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Backshop":{"tags":{"name":"Backshop","shop":"bakery"},"name":"Backshop","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Backwerk":{"tags":{"name":"Backwerk","shop":"bakery"},"name":"Backwerk","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Baguette":{"tags":{"name":"Baguette","shop":"bakery"},"name":"Baguette","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bakers Delight":{"tags":{"name":"Bakers Delight","shop":"bakery"},"name":"Bakers Delight","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bakker Bart":{"tags":{"name":"Bakker Bart","shop":"bakery"},"name":"Bakker Bart","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Banette":{"tags":{"name":"Banette","shop":"bakery"},"name":"Banette","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bäckerei Fuchs":{"tags":{"name":"Bäckerei Fuchs","shop":"bakery"},"name":"Bäckerei Fuchs","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bäckerei Grimminger":{"tags":{"name":"Bäckerei Grimminger","shop":"bakery"},"name":"Bäckerei Grimminger","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bäckerei Müller":{"tags":{"name":"Bäckerei Müller","shop":"bakery"},"name":"Bäckerei Müller","icon":"bakery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bäckerei Schneider":{"tags":{"name":"Bäckerei Schneider","shop":"bakery"},"name":"Bäckerei Schneider","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Cooplands":{"tags":{"name":"Cooplands","shop":"bakery"},"name":"Cooplands","icon":"bakery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Der Mann":{"tags":{"name":"Der Mann","shop":"bakery"},"name":"Der Mann","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Ditsch":{"tags":{"name":"Ditsch","shop":"bakery"},"name":"Ditsch","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Fornetti":{"tags":{"name":"Fornetti","shop":"bakery"},"name":"Fornetti","icon":"bakery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Goldilocks":{"tags":{"name":"Goldilocks","shop":"bakery"},"name":"Goldilocks","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Greggs":{"tags":{"name":"Greggs","shop":"bakery"},"name":"Greggs","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Hofpfisterei":{"tags":{"name":"Hofpfisterei","shop":"bakery"},"name":"Hofpfisterei","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Ihle":{"tags":{"name":"Ihle","shop":"bakery"},"name":"Ihle","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Julie's Bakeshop":{"tags":{"name":"Julie's Bakeshop","shop":"bakery"},"name":"Julie's Bakeshop","icon":"bakery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/K&U Bäckerei":{"tags":{"name":"K&U Bäckerei","shop":"bakery"},"name":"K&U Bäckerei","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Kamps":{"tags":{"name":"Kamps","shop":"bakery"},"name":"Kamps","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/La Mie Câline":{"tags":{"name":"La Mie Câline","shop":"bakery"},"name":"La Mie Câline","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Le Crobag":{"tags":{"name":"Le Crobag","shop":"bakery"},"name":"Le Crobag","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Le Fournil":{"tags":{"name":"Le Fournil","shop":"bakery"},"name":"Le Fournil","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Lila Bäcker":{"tags":{"name":"Lila Bäcker","shop":"bakery"},"name":"Lila Bäcker","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Lipóti Pékség":{"tags":{"name":"Lipóti Pékség","shop":"bakery"},"name":"Lipóti Pékség","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Marie Blachère":{"tags":{"name":"Marie Blachère","shop":"bakery"},"name":"Marie Blachère","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Mlinar":{"tags":{"name":"Mlinar","shop":"bakery"},"name":"Mlinar","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Musmanni":{"tags":{"name":"Musmanni","shop":"bakery"},"name":"Musmanni","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Oebel":{"tags":{"name":"Oebel","shop":"bakery"},"name":"Oebel","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Panaderia":{"tags":{"name":"Panaderia","shop":"bakery"},"name":"Panaderia","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Paul":{"tags":{"name":"Paul","shop":"bakery"},"name":"Paul","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Red Ribbon":{"tags":{"name":"Red Ribbon","shop":"bakery"},"name":"Red Ribbon","icon":"bakery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Sehne":{"tags":{"name":"Sehne","shop":"bakery"},"name":"Sehne","icon":"bakery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Steinecke":{"tags":{"name":"Steinecke","shop":"bakery"},"name":"Steinecke","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Sternenbäck":{"tags":{"name":"Sternenbäck","shop":"bakery"},"name":"Sternenbäck","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Ströck":{"tags":{"name":"Ströck","shop":"bakery"},"name":"Ströck","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Wiener Feinbäcker":{"tags":{"name":"Wiener Feinbäcker","shop":"bakery"},"name":"Wiener Feinbäcker","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/von Allwörden":{"tags":{"name":"von Allwörden","shop":"bakery"},"name":"von Allwörden","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Булочная":{"tags":{"name":"Булочная","shop":"bakery"},"name":"Булочная","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Горячий хлеб":{"tags":{"name":"Горячий хлеб","shop":"bakery"},"name":"Горячий хлеб","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Каравай":{"tags":{"name":"Каравай","shop":"bakery"},"name":"Каравай","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Кулиничи":{"tags":{"name":"Кулиничи","shop":"bakery"},"name":"Кулиничи","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Кулиничі":{"tags":{"name":"Кулиничі","shop":"bakery"},"name":"Кулиничі","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Свежий хлеб":{"tags":{"name":"Свежий хлеб","shop":"bakery"},"name":"Свежий хлеб","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Хлеб":{"tags":{"name":"Хлеб","shop":"bakery"},"name":"Хлеб","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/مخبز":{"tags":{"name":"مخبز","shop":"bakery"},"name":"مخبز","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/مخبزة":{"tags":{"name":"مخبزة","shop":"bakery"},"name":"مخبزة","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/نان لواش":{"tags":{"name":"نان لواش","shop":"bakery"},"name":"نان لواش","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/نانوایی":{"tags":{"name":"نانوایی","shop":"bakery"},"name":"نانوایی","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/نانوایی بربری":{"tags":{"name":"نانوایی بربری","shop":"bakery"},"name":"نانوایی بربری","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/نانوایی سنگک":{"tags":{"name":"نانوایی سنگک","shop":"bakery"},"name":"نانوایی سنگک","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/نانوایی سنگکی":{"tags":{"name":"نانوایی سنگکی","shop":"bakery"},"name":"نانوایی سنگکی","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/نانوایی لواش":{"tags":{"name":"نانوایی لواش","shop":"bakery"},"name":"نانوایی لواش","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beauty/Sally Beauty Supply":{"tags":{"name":"Sally Beauty Supply","shop":"beauty"},"name":"Sally Beauty Supply","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","beauty"],"suggestion":true},"shop/beauty/Yves Rocher":{"tags":{"name":"Yves Rocher","shop":"beauty"},"name":"Yves Rocher","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","beauty"],"suggestion":true},"shop/bed/Matratzen Concord":{"tags":{"name":"Matratzen Concord","shop":"bed"},"name":"Matratzen Concord","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bed/Mattress Firm":{"tags":{"name":"Mattress Firm","shop":"bed"},"name":"Mattress Firm","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bed/Sleepy's":{"tags":{"name":"Sleepy's","shop":"bed"},"name":"Sleepy's","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/50嵐":{"tags":{"name":"50嵐","shop":"beverages"},"name":"50嵐","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Dursty":{"tags":{"name":"Dursty","shop":"beverages"},"name":"Dursty","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Edeka Getränkemarkt":{"tags":{"name":"Edeka Getränkemarkt","shop":"beverages"},"name":"Edeka Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Fristo":{"tags":{"name":"Fristo","shop":"beverages"},"name":"Fristo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Getränke Hoffmann":{"tags":{"name":"Getränke Hoffmann","shop":"beverages"},"name":"Getränke Hoffmann","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Getränkeland":{"tags":{"name":"Getränkeland","shop":"beverages"},"name":"Getränkeland","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Getränkemarkt":{"tags":{"name":"Getränkemarkt","shop":"beverages"},"name":"Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Orterer Getränkemarkt":{"tags":{"name":"Orterer Getränkemarkt","shop":"beverages"},"name":"Orterer Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/REWE Getränkemarkt":{"tags":{"name":"REWE Getränkemarkt","shop":"beverages"},"name":"REWE Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/Trinkgut":{"tags":{"name":"Trinkgut","shop":"beverages"},"name":"Trinkgut","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/beverages/茶湯會":{"tags":{"name":"茶湯會","shop":"beverages"},"name":"茶湯會","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bicycle/Halfords":{"tags":{"name":"Halfords","shop":"bicycle"},"name":"Halfords","icon":"bicycle","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/bicycle"],"suggestion":true},"shop/bicycle/Веломарка":{"tags":{"name":"Веломарка","shop":"bicycle"},"name":"Веломарка","icon":"bicycle","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/bicycle"],"suggestion":true},"shop/bicycle/サイクルベースあさひ":{"tags":{"name":"サイクルベースあさひ","shop":"bicycle"},"name":"サイクルベースあさひ","icon":"bicycle","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/bicycle"],"suggestion":true},"shop/bookmaker/Betfred":{"tags":{"name":"Betfred","shop":"bookmaker"},"name":"Betfred","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bookmaker/Coral":{"tags":{"name":"Coral","shop":"bookmaker"},"name":"Coral","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bookmaker/Ladbrokes":{"tags":{"name":"Ladbrokes","shop":"bookmaker"},"name":"Ladbrokes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bookmaker/Paddy Power":{"tags":{"name":"Paddy Power","shop":"bookmaker"},"name":"Paddy Power","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bookmaker/William Hill":{"tags":{"name":"William Hill","shop":"bookmaker"},"name":"William Hill","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/bookmaker/ΟΠΑΠ":{"tags":{"name":"ΟΠΑΠ","shop":"bookmaker"},"name":"ΟΠΑΠ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Boucherie Charcuterie":{"tags":{"name":"Boucherie Charcuterie","shop":"butcher"},"name":"Boucherie Charcuterie","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Carnicería":{"tags":{"name":"Carnicería","shop":"butcher"},"name":"Carnicería","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Fleischerei Richter":{"tags":{"name":"Fleischerei Richter","shop":"butcher"},"name":"Fleischerei Richter","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Húsbolt":{"tags":{"name":"Húsbolt","shop":"butcher"},"name":"Húsbolt","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Macelleria":{"tags":{"name":"Macelleria","shop":"butcher"},"name":"Macelleria","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Vinzenzmurr":{"tags":{"name":"Vinzenzmurr","shop":"butcher"},"name":"Vinzenzmurr","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Ариант":{"tags":{"name":"Ариант","shop":"butcher"},"name":"Ариант","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Великолукский мясокомбинат":{"tags":{"name":"Великолукский мясокомбинат","shop":"butcher"},"name":"Великолукский мясокомбинат","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Мясная лавка":{"tags":{"name":"Мясная лавка","shop":"butcher"},"name":"Мясная лавка","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Мясницкий ряд":{"tags":{"name":"Мясницкий ряд","shop":"butcher"},"name":"Мясницкий ряд","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Мясной":{"tags":{"name":"Мясной","shop":"butcher"},"name":"Мясной","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Мясо":{"tags":{"name":"Мясо","shop":"butcher"},"name":"Мясо","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Наша Ряба":{"tags":{"name":"Наша Ряба","shop":"butcher"},"name":"Наша Ряба","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/butcher/Свежее мясо":{"tags":{"name":"Свежее мясо","shop":"butcher"},"name":"Свежее мясо","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car/Audi":{"tags":{"name":"Audi","shop":"car"},"name":"Audi","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/BMW":{"tags":{"name":"BMW","shop":"car"},"name":"BMW","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Chevrolet":{"tags":{"name":"Chevrolet","shop":"car"},"name":"Chevrolet","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Citroen":{"tags":{"name":"Citroen","shop":"car"},"name":"Citroen","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Dacia":{"tags":{"name":"Dacia","shop":"car"},"name":"Dacia","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Fiat":{"tags":{"name":"Fiat","shop":"car"},"name":"Fiat","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Ford":{"tags":{"name":"Ford","shop":"car"},"name":"Ford","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Honda":{"tags":{"name":"Honda","shop":"car"},"name":"Honda","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Hyundai":{"tags":{"name":"Hyundai","shop":"car"},"name":"Hyundai","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Isuzu":{"tags":{"name":"Isuzu","shop":"car"},"name":"Isuzu","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Kia":{"tags":{"name":"Kia","shop":"car"},"name":"Kia","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Land Rover":{"tags":{"name":"Land Rover","shop":"car"},"name":"Land Rover","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Lexus":{"tags":{"name":"Lexus","shop":"car"},"name":"Lexus","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Mazda":{"tags":{"name":"Mazda","shop":"car"},"name":"Mazda","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Mercedes-Benz":{"tags":{"name":"Mercedes-Benz","shop":"car"},"name":"Mercedes-Benz","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Mitsubishi":{"tags":{"name":"Mitsubishi","shop":"car"},"name":"Mitsubishi","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Mitsubishi Motors":{"tags":{"name":"Mitsubishi Motors","shop":"car"},"name":"Mitsubishi Motors","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/NISSAN":{"tags":{"name":"NISSAN","shop":"car"},"name":"NISSAN","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Nissan":{"tags":{"name":"Nissan","shop":"car"},"name":"Nissan","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Opel":{"tags":{"name":"Opel","shop":"car"},"name":"Opel","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Peugeot":{"tags":{"name":"Peugeot","shop":"car"},"name":"Peugeot","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Porsche":{"tags":{"name":"Porsche","shop":"car"},"name":"Porsche","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Renault":{"tags":{"name":"Renault","shop":"car"},"name":"Renault","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Seat":{"tags":{"name":"Seat","shop":"car"},"name":"Seat","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Skoda":{"tags":{"name":"Skoda","shop":"car"},"name":"Skoda","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Subaru":{"tags":{"name":"Subaru","shop":"car"},"name":"Subaru","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Suzuki":{"tags":{"name":"Suzuki","shop":"car"},"name":"Suzuki","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Toyota":{"tags":{"name":"Toyota","shop":"car"},"name":"Toyota","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Volkswagen":{"tags":{"name":"Volkswagen","shop":"car"},"name":"Volkswagen","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car/Volvo":{"tags":{"name":"Volvo","shop":"car"},"name":"Volvo","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand","service/vehicle"],"suggestion":true},"shop/car_parts/Advance Auto Parts":{"tags":{"name":"Advance Auto Parts","shop":"car_parts"},"name":"Advance Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/AutoZone":{"tags":{"name":"AutoZone","shop":"car_parts"},"name":"AutoZone","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/Brezan":{"tags":{"name":"Brezan","shop":"car_parts"},"name":"Brezan","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/NAPA Auto Parts":{"tags":{"name":"NAPA Auto Parts","shop":"car_parts"},"name":"NAPA Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/Napa Auto Parts":{"tags":{"name":"Napa Auto Parts","shop":"car_parts"},"name":"Napa Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/O'Reilly Auto Parts":{"tags":{"name":"O'Reilly Auto Parts","shop":"car_parts"},"name":"O'Reilly Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/Repco":{"tags":{"name":"Repco","shop":"car_parts"},"name":"Repco","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/Tokić":{"tags":{"name":"Tokić","shop":"car_parts"},"name":"Tokić","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/repuestos automotrices":{"tags":{"name":"repuestos automotrices","shop":"car_parts"},"name":"repuestos automotrices","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/Автозапчастини":{"tags":{"name":"Автозапчастини","shop":"car_parts"},"name":"Автозапчастини","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/Автомир":{"tags":{"name":"Автомир","shop":"car_parts"},"name":"Автомир","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/イエローハット":{"tags":{"name":"イエローハット","shop":"car_parts"},"name":"イエローハット","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/オートバックス":{"tags":{"name":"オートバックス","shop":"car_parts"},"name":"オートバックス","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_parts/タイヤ館":{"tags":{"name":"タイヤ館","shop":"car_parts"},"name":"タイヤ館","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/A.T.U":{"tags":{"name":"A.T.U","shop":"car_repair"},"name":"A.T.U","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Bosch Car Service":{"tags":{"name":"Bosch Car Service","shop":"car_repair"},"name":"Bosch Car Service","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Carglass":{"tags":{"name":"Carglass","shop":"car_repair"},"name":"Carglass","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Euromaster":{"tags":{"name":"Euromaster","shop":"car_repair"},"name":"Euromaster","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Feu Vert":{"tags":{"name":"Feu Vert","shop":"car_repair"},"name":"Feu Vert","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Firestone":{"tags":{"name":"Firestone","shop":"car_repair"},"name":"Firestone","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Firestone Complete Auto Care":{"tags":{"name":"Firestone Complete Auto Care","shop":"car_repair"},"name":"Firestone Complete Auto Care","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Garage Renault":{"tags":{"name":"Garage Renault","shop":"car_repair"},"name":"Garage Renault","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Gomeria":{"tags":{"name":"Gomeria","shop":"car_repair"},"name":"Gomeria","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Gomería":{"tags":{"name":"Gomería","shop":"car_repair"},"name":"Gomería","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Goodyear":{"tags":{"name":"Goodyear","shop":"car_repair"},"name":"Goodyear","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Grease Monkey":{"tags":{"name":"Grease Monkey","shop":"car_repair"},"name":"Grease Monkey","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Jiffy Lube":{"tags":{"name":"Jiffy Lube","shop":"car_repair"},"name":"Jiffy Lube","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Kwik Fit":{"tags":{"name":"Kwik Fit","shop":"car_repair"},"name":"Kwik Fit","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Lubricentro":{"tags":{"name":"Lubricentro","shop":"car_repair"},"name":"Lubricentro","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Meineke":{"tags":{"name":"Meineke","shop":"car_repair"},"name":"Meineke","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Mekonomen":{"tags":{"name":"Mekonomen","shop":"car_repair"},"name":"Mekonomen","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Midas":{"tags":{"name":"Midas","shop":"car_repair"},"name":"Midas","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Mr. Lube":{"tags":{"name":"Mr. Lube","shop":"car_repair"},"name":"Mr. Lube","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Norauto":{"tags":{"name":"Norauto","shop":"car_repair"},"name":"Norauto","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Pep Boys":{"tags":{"name":"Pep Boys","shop":"car_repair"},"name":"Pep Boys","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Pit Stop":{"tags":{"name":"Pit Stop","shop":"car_repair"},"name":"Pit Stop","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Point S":{"tags":{"name":"Point S","shop":"car_repair"},"name":"Point S","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Roady":{"tags":{"name":"Roady","shop":"car_repair"},"name":"Roady","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Sears Auto Center":{"tags":{"name":"Sears Auto Center","shop":"car_repair"},"name":"Sears Auto Center","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Speedy":{"tags":{"name":"Speedy","shop":"car_repair"},"name":"Speedy","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Stacja Kontroli Pojazdów":{"tags":{"name":"Stacja Kontroli Pojazdów","shop":"car_repair"},"name":"Stacja Kontroli Pojazdów","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Taller":{"tags":{"name":"Taller","shop":"car_repair"},"name":"Taller","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Valvoline":{"tags":{"name":"Valvoline","shop":"car_repair"},"name":"Valvoline","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Valvoline Instant Oil Change":{"tags":{"name":"Valvoline Instant Oil Change","shop":"car_repair"},"name":"Valvoline Instant Oil Change","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Wulkanizacja":{"tags":{"name":"Wulkanizacja","shop":"car_repair"},"name":"Wulkanizacja","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/ÖAMTC":{"tags":{"name":"ÖAMTC","shop":"car_repair"},"name":"ÖAMTC","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Автомастерская":{"tags":{"name":"Автомастерская","shop":"car_repair"},"name":"Автомастерская","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Авторемонт":{"tags":{"name":"Авторемонт","shop":"car_repair"},"name":"Авторемонт","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Автосервис":{"tags":{"name":"Автосервис","shop":"car_repair"},"name":"Автосервис","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Автосервис+шиномонтаж":{"tags":{"name":"Автосервис+шиномонтаж","shop":"car_repair"},"name":"Автосервис+шиномонтаж","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Замена масла":{"tags":{"name":"Замена масла","shop":"car_repair"},"name":"Замена масла","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/СТО":{"tags":{"name":"СТО","shop":"car_repair"},"name":"СТО","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/Шиномонтаж":{"tags":{"name":"Шиномонтаж","shop":"car_repair"},"name":"Шиномонтаж","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/car_repair/шиномонтаж":{"tags":{"name":"шиномонтаж","shop":"car_repair"},"name":"шиномонтаж","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","service/vehicle"],"suggestion":true},"shop/carpet/Carpet Right":{"tags":{"name":"Carpet Right","shop":"carpet"},"name":"Carpet Right","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/carpet/Carpetright":{"tags":{"name":"Carpetright","shop":"carpet"},"name":"Carpetright","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/charity/Age UK":{"tags":{"name":"Age UK","shop":"charity"},"name":"Age UK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/Barnardo's":{"tags":{"name":"Barnardo's","shop":"charity"},"name":"Barnardo's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/British Heart Foundation":{"tags":{"name":"British Heart Foundation","shop":"charity"},"name":"British Heart Foundation","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/Cancer Research UK":{"tags":{"name":"Cancer Research UK","shop":"charity"},"name":"Cancer Research UK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/Oxfam":{"tags":{"name":"Oxfam","shop":"charity"},"name":"Oxfam","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/Salvation Army":{"tags":{"name":"Salvation Army","shop":"charity"},"name":"Salvation Army","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/Scope":{"tags":{"name":"Scope","shop":"charity"},"name":"Scope","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/charity/Sue Ryder":{"tags":{"name":"Sue Ryder","shop":"charity"},"name":"Sue Ryder","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/chemist/7 Дней":{"tags":{"name":"7 Дней","shop":"chemist"},"name":"7 Дней","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Bipa":{"tags":{"name":"Bipa","shop":"chemist"},"name":"Bipa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Budnikowsky":{"tags":{"name":"Budnikowsky","shop":"chemist"},"name":"Budnikowsky","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Etos":{"tags":{"name":"Etos","shop":"chemist"},"name":"Etos","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Kruidvat":{"tags":{"name":"Kruidvat","shop":"chemist"},"name":"Kruidvat","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Matas":{"tags":{"name":"Matas","shop":"chemist"},"name":"Matas","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Rossmann":{"tags":{"name":"Rossmann","shop":"chemist"},"name":"Rossmann","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Schlecker":{"tags":{"name":"Schlecker","shop":"chemist"},"name":"Schlecker","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Teta":{"tags":{"name":"Teta","shop":"chemist"},"name":"Teta","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Trekpleister":{"tags":{"name":"Trekpleister","shop":"chemist"},"name":"Trekpleister","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Watsons":{"tags":{"name":"Watsons","shop":"chemist"},"name":"Watsons","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/dm":{"tags":{"name":"dm","shop":"chemist"},"name":"dm","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Бытовая химия":{"tags":{"name":"Бытовая химия","shop":"chemist"},"name":"Бытовая химия","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Магнит Косметик":{"tags":{"name":"Магнит Косметик","shop":"chemist"},"name":"Магнит Косметик","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Мила":{"tags":{"name":"Мила","shop":"chemist"},"name":"Мила","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Остров чистоты":{"tags":{"name":"Остров чистоты","shop":"chemist"},"name":"Остров чистоты","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Рубль Бум":{"tags":{"name":"Рубль Бум","shop":"chemist"},"name":"Рубль Бум","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Улыбка радуги":{"tags":{"name":"Улыбка радуги","shop":"chemist"},"name":"Улыбка радуги","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/屈臣氏":{"tags":{"name":"屈臣氏","shop":"chemist"},"name":"屈臣氏","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/康是美":{"tags":{"name":"康是美","shop":"chemist"},"name":"康是美","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/American Eagle Outfitters":{"tags":{"name":"American Eagle Outfitters","shop":"clothes"},"name":"American Eagle Outfitters","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Anthropologie":{"tags":{"name":"Anthropologie","shop":"clothes"},"name":"Anthropologie","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ardene":{"tags":{"name":"Ardene","shop":"clothes"},"name":"Ardene","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Armand Thiery":{"tags":{"name":"Armand Thiery","shop":"clothes"},"name":"Armand Thiery","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Bershka":{"tags":{"name":"Bershka","shop":"clothes"},"name":"Bershka","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Bonobo":{"tags":{"name":"Bonobo","shop":"clothes"},"name":"Bonobo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Brooks Brothers":{"tags":{"name":"Brooks Brothers","shop":"clothes"},"name":"Brooks Brothers","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Burberry":{"tags":{"name":"Burberry","shop":"clothes"},"name":"Burberry","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Burlington Coat Factory":{"tags":{"name":"Burlington Coat Factory","shop":"clothes"},"name":"Burlington Coat Factory","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Cache Cache":{"tags":{"name":"Cache Cache","shop":"clothes"},"name":"Cache Cache","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Calvin Klein":{"tags":{"name":"Calvin Klein","shop":"clothes"},"name":"Calvin Klein","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Camaïeu":{"tags":{"name":"Camaïeu","shop":"clothes"},"name":"Camaïeu","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Caroll":{"tags":{"name":"Caroll","shop":"clothes"},"name":"Caroll","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Carter's":{"tags":{"name":"Carter's","shop":"clothes"},"name":"Carter's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Chico's":{"tags":{"name":"Chico's","shop":"clothes"},"name":"Chico's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Cropp":{"tags":{"name":"Cropp","shop":"clothes"},"name":"Cropp","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Cubus":{"tags":{"name":"Cubus","shop":"clothes"},"name":"Cubus","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Desigual":{"tags":{"name":"Desigual","shop":"clothes"},"name":"Desigual","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Devred":{"tags":{"name":"Devred","shop":"clothes"},"name":"Devred","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Didi":{"tags":{"name":"Didi","shop":"clothes"},"name":"Didi","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Diesel":{"tags":{"name":"Diesel","shop":"clothes"},"name":"Diesel","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Dressmann":{"tags":{"name":"Dressmann","shop":"clothes"},"name":"Dressmann","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Eddie Bauer":{"tags":{"name":"Eddie Bauer","shop":"clothes"},"name":"Eddie Bauer","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Engbers":{"tags":{"name":"Engbers","shop":"clothes"},"name":"Engbers","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Express":{"tags":{"name":"Express","shop":"clothes"},"name":"Express","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Fat Face":{"tags":{"name":"Fat Face","shop":"clothes"},"name":"Fat Face","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Forever 21":{"tags":{"name":"Forever 21","shop":"clothes"},"name":"Forever 21","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gant":{"tags":{"name":"Gant","shop":"clothes"},"name":"Gant","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gina Laura":{"tags":{"name":"Gina Laura","shop":"clothes"},"name":"Gina Laura","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Guess":{"tags":{"name":"Guess","shop":"clothes"},"name":"Guess","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gymboree":{"tags":{"name":"Gymboree","shop":"clothes"},"name":"Gymboree","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gémo":{"tags":{"name":"Gémo","shop":"clothes"},"name":"Gémo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Hallhuber":{"tags":{"name":"Hallhuber","shop":"clothes"},"name":"Hallhuber","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/House":{"tags":{"name":"House","shop":"clothes"},"name":"House","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Hugo Boss":{"tags":{"name":"Hugo Boss","shop":"clothes"},"name":"Hugo Boss","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Humana":{"tags":{"name":"Humana","shop":"clothes"},"name":"Humana","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Hunkemöller":{"tags":{"name":"Hunkemöller","shop":"clothes"},"name":"Hunkemöller","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/JBC":{"tags":{"name":"JBC","shop":"clothes"},"name":"JBC","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jennyfer":{"tags":{"name":"Jennyfer","shop":"clothes"},"name":"Jennyfer","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jigsaw":{"tags":{"name":"Jigsaw","shop":"clothes"},"name":"Jigsaw","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Justice":{"tags":{"name":"Justice","shop":"clothes"},"name":"Justice","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/KappAhl":{"tags":{"name":"KappAhl","shop":"clothes"},"name":"KappAhl","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Lane Bryant":{"tags":{"name":"Lane Bryant","shop":"clothes"},"name":"Lane Bryant","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Loft":{"tags":{"name":"Loft","shop":"clothes"},"name":"Loft","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Marc O'Polo":{"tags":{"name":"Marc O'Polo","shop":"clothes"},"name":"Marc O'Polo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mark's":{"tags":{"name":"Mark's","shop":"clothes"},"name":"Mark's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Massimo Dutti":{"tags":{"name":"Massimo Dutti","shop":"clothes"},"name":"Massimo Dutti","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Matalan":{"tags":{"name":"Matalan","shop":"clothes"},"name":"Matalan","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Maurices":{"tags":{"name":"Maurices","shop":"clothes"},"name":"Maurices","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Max Mara":{"tags":{"name":"Max Mara","shop":"clothes"},"name":"Max Mara","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Michael Kors":{"tags":{"name":"Michael Kors","shop":"clothes"},"name":"Michael Kors","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mim":{"tags":{"name":"Mim","shop":"clothes"},"name":"Mim","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Monsoon":{"tags":{"name":"Monsoon","shop":"clothes"},"name":"Monsoon","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/NewYorker":{"tags":{"name":"NewYorker","shop":"clothes"},"name":"NewYorker","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Nike":{"tags":{"name":"Nike","shop":"clothes"},"name":"Nike","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Nordstrom Rack":{"tags":{"name":"Nordstrom Rack","shop":"clothes"},"name":"Nordstrom Rack","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/OVS":{"tags":{"name":"OVS","shop":"clothes"},"name":"OVS","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Okaïdi":{"tags":{"name":"Okaïdi","shop":"clothes"},"name":"Okaïdi","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Only":{"tags":{"name":"Only","shop":"clothes"},"name":"Only","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Orchestra":{"tags":{"name":"Orchestra","shop":"clothes"},"name":"Orchestra","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Original Marines":{"tags":{"name":"Original Marines","shop":"clothes"},"name":"Original Marines","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Outfit":{"tags":{"name":"Outfit","shop":"clothes"},"name":"Outfit","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Outlet":{"tags":{"name":"Outlet","shop":"clothes"},"name":"Outlet","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Palmers":{"tags":{"name":"Palmers","shop":"clothes"},"name":"Palmers","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Peek & Cloppenburg":{"tags":{"name":"Peek & Cloppenburg","shop":"clothes"},"name":"Peek & Cloppenburg","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Pepco":{"tags":{"name":"Pepco","shop":"clothes"},"name":"Pepco","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Petit Bateau":{"tags":{"name":"Petit Bateau","shop":"clothes"},"name":"Petit Bateau","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Plato's Closet":{"tags":{"name":"Plato's Closet","shop":"clothes"},"name":"Plato's Closet","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Pull & Bear":{"tags":{"name":"Pull & Bear","shop":"clothes"},"name":"Pull & Bear","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Reitmans":{"tags":{"name":"Reitmans","shop":"clothes"},"name":"Reitmans","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Reserved":{"tags":{"name":"Reserved","shop":"clothes"},"name":"Reserved","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Sela":{"tags":{"name":"Sela","shop":"clothes"},"name":"Sela","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Sergent Major":{"tags":{"name":"Sergent Major","shop":"clothes"},"name":"Sergent Major","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Shoeby":{"tags":{"name":"Shoeby","shop":"clothes"},"name":"Shoeby","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Sisley":{"tags":{"name":"Sisley","shop":"clothes"},"name":"Sisley","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Springfield":{"tags":{"name":"Springfield","shop":"clothes"},"name":"Springfield","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Stefanel":{"tags":{"name":"Stefanel","shop":"clothes"},"name":"Stefanel","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Steps":{"tags":{"name":"Steps","shop":"clothes"},"name":"Steps","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Stradivarius":{"tags":{"name":"Stradivarius","shop":"clothes"},"name":"Stradivarius","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Superdry":{"tags":{"name":"Superdry","shop":"clothes"},"name":"Superdry","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Talbots":{"tags":{"name":"Talbots","shop":"clothes"},"name":"Talbots","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tati":{"tags":{"name":"Tati","shop":"clothes"},"name":"Tati","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Terranova":{"tags":{"name":"Terranova","shop":"clothes"},"name":"Terranova","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tesha":{"tags":{"name":"Tesha","shop":"clothes"},"name":"Tesha","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tezenis":{"tags":{"name":"Tezenis","shop":"clothes"},"name":"Tezenis","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/The Children's Place":{"tags":{"name":"The Children's Place","shop":"clothes"},"name":"The Children's Place","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/The North Face":{"tags":{"name":"The North Face","shop":"clothes"},"name":"The North Face","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/The Sting":{"tags":{"name":"The Sting","shop":"clothes"},"name":"The Sting","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Timberland":{"tags":{"name":"Timberland","shop":"clothes"},"name":"Timberland","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Toko Pakaian":{"tags":{"name":"Toko Pakaian","shop":"clothes"},"name":"Toko Pakaian","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tom Tailor":{"tags":{"name":"Tom Tailor","shop":"clothes"},"name":"Tom Tailor","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Topshop":{"tags":{"name":"Topshop","shop":"clothes"},"name":"Topshop","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Triumph":{"tags":{"name":"Triumph","shop":"clothes"},"name":"Triumph","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Uniqlo":{"tags":{"name":"Uniqlo","shop":"clothes"},"name":"Uniqlo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Victoria's Secret":{"tags":{"name":"Victoria's Secret","shop":"clothes"},"name":"Victoria's Secret","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/WE":{"tags":{"name":"WE","shop":"clothes"},"name":"WE","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Wibra":{"tags":{"name":"Wibra","shop":"clothes"},"name":"Wibra","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Yamamay":{"tags":{"name":"Yamamay","shop":"clothes"},"name":"Yamamay","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/mister*lady":{"tags":{"name":"mister*lady","shop":"clothes"},"name":"mister*lady","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","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":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Детская одежда":{"tags":{"name":"Детская одежда","shop":"clothes"},"name":"Детская одежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Женская одежда":{"tags":{"name":"Женская одежда","shop":"clothes"},"name":"Женская одежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Липненски":{"tags":{"name":"Липненски","shop":"clothes"},"name":"Липненски","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Московская ярмарка":{"tags":{"name":"Московская ярмарка","shop":"clothes"},"name":"Московская ярмарка","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Одежда":{"tags":{"name":"Одежда","shop":"clothes"},"name":"Одежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Смешные цены":{"tags":{"name":"Смешные цены","shop":"clothes"},"name":"Смешные цены","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Спецодежда":{"tags":{"name":"Спецодежда","shop":"clothes"},"name":"Спецодежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/しまむら":{"tags":{"name":"しまむら","shop":"clothes"},"name":"しまむら","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/ユニクロ":{"tags":{"name":"ユニクロ","shop":"clothes"},"name":"ユニクロ","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/ワークマン":{"tags":{"name":"ワークマン","shop":"clothes"},"name":"ワークマン","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/洋服の青山":{"tags":{"name":"洋服の青山","shop":"clothes"},"name":"洋服の青山","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/西松屋":{"tags":{"name":"西松屋","shop":"clothes"},"name":"西松屋","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours"],"suggestion":true},"shop/coffee/Nespresso":{"tags":{"name":"Nespresso","shop":"coffee"},"name":"Nespresso","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/coffee/Tchibo":{"tags":{"name":"Tchibo","shop":"coffee"},"name":"Tchibo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/Apple Store":{"tags":{"name":"Apple Store","shop":"computer"},"name":"Apple Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/DNS":{"tags":{"name":"DNS","shop":"computer"},"name":"DNS","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/ДНС":{"tags":{"name":"ДНС","shop":"computer"},"name":"ДНС","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/confectionery/Fagyizó":{"tags":{"name":"Fagyizó","shop":"confectionery"},"name":"Fagyizó","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/confectionery/Hussel":{"tags":{"name":"Hussel","shop":"confectionery"},"name":"Hussel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/confectionery/Leonidas":{"tags":{"name":"Leonidas","shop":"confectionery"},"name":"Leonidas","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/confectionery/T. SN":{"tags":{"name":"T. SN","shop":"confectionery"},"name":"T. SN","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/confectionery/Thorntons":{"tags":{"name":"Thorntons","shop":"confectionery"},"name":"Thorntons","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/711":{"tags":{"name":"711","shop":"convenience"},"name":"711","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/777":{"tags":{"name":"777","shop":"convenience"},"name":"777","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/24 часа":{"tags":{"name":"24 часа","shop":"convenience"},"name":"24 часа","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/99 Speedmart":{"tags":{"name":"99 Speedmart","shop":"convenience"},"name":"99 Speedmart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ABC":{"tags":{"name":"ABC","shop":"convenience"},"name":"ABC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/AMPM":{"tags":{"name":"AMPM","shop":"convenience"},"name":"AMPM","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Aibė":{"tags":{"name":"Aibė","shop":"convenience"},"name":"Aibė","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alepa":{"tags":{"name":"Alepa","shop":"convenience"},"name":"Alepa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alfamart":{"tags":{"name":"Alfamart","shop":"convenience"},"name":"Alfamart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alimentara":{"tags":{"name":"Alimentara","shop":"convenience"},"name":"Alimentara","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Almacen":{"tags":{"name":"Almacen","shop":"convenience"},"name":"Almacen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Almacén":{"tags":{"name":"Almacén","shop":"convenience"},"name":"Almacén","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/BP Shop":{"tags":{"name":"BP Shop","shop":"convenience"},"name":"BP Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Baqala":{"tags":{"name":"Baqala","shop":"convenience"},"name":"Baqala","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Best One":{"tags":{"name":"Best One","shop":"convenience"},"name":"Best One","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Best-One":{"tags":{"name":"Best-One","shop":"convenience"},"name":"Best-One","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Bodega":{"tags":{"name":"Bodega","shop":"convenience"},"name":"Bodega","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Bonjour":{"tags":{"name":"Bonjour","shop":"convenience"},"name":"Bonjour","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Boutique":{"tags":{"name":"Boutique","shop":"convenience"},"name":"Boutique","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/CBA":{"tags":{"name":"CBA","shop":"convenience"},"name":"CBA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/COOP":{"tags":{"name":"COOP","shop":"convenience"},"name":"COOP","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/CU":{"tags":{"name":"CU","shop":"convenience"},"name":"CU","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Casino Shop":{"tags":{"name":"Casino Shop","shop":"convenience"},"name":"Casino Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Centra":{"tags":{"name":"Centra","shop":"convenience"},"name":"Centra","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Corner Store":{"tags":{"name":"Corner Store","shop":"convenience"},"name":"Corner Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Costcutter":{"tags":{"name":"Costcutter","shop":"convenience"},"name":"Costcutter","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Couche-Tard":{"tags":{"name":"Couche-Tard","shop":"convenience"},"name":"Couche-Tard","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Daisy Mart":{"tags":{"name":"Daisy Mart","shop":"convenience"},"name":"Daisy Mart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Delikatesy":{"tags":{"name":"Delikatesy","shop":"convenience"},"name":"Delikatesy","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Dépanneur":{"tags":{"name":"Dépanneur","shop":"convenience"},"name":"Dépanneur","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/FamilyMart":{"tags":{"name":"FamilyMart","shop":"convenience"},"name":"FamilyMart","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Fresh":{"tags":{"name":"Fresh","shop":"convenience"},"name":"Fresh","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Freshmarket":{"tags":{"name":"Freshmarket","shop":"convenience"},"name":"Freshmarket","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/GS25":{"tags":{"name":"GS25","shop":"convenience"},"name":"GS25","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Groszek":{"tags":{"name":"Groszek","shop":"convenience"},"name":"Groszek","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Hruška":{"tags":{"name":"Hruška","shop":"convenience"},"name":"Hruška","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Indomaret":{"tags":{"name":"Indomaret","shop":"convenience"},"name":"Indomaret","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Jednota":{"tags":{"name":"Jednota","shop":"convenience"},"name":"Jednota","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Joker":{"tags":{"name":"Joker","shop":"convenience"},"name":"Joker","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Kangaroo Express":{"tags":{"name":"Kangaroo Express","shop":"convenience"},"name":"Kangaroo Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Kisbolt":{"tags":{"name":"Kisbolt","shop":"convenience"},"name":"Kisbolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/LAWSON":{"tags":{"name":"LAWSON","shop":"convenience"},"name":"LAWSON","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Lewiatan":{"tags":{"name":"Lewiatan","shop":"convenience"},"name":"Lewiatan","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Lifestyle Express":{"tags":{"name":"Lifestyle Express","shop":"convenience"},"name":"Lifestyle Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Londis":{"tags":{"name":"Londis","shop":"convenience"},"name":"Londis","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/M&S Simply Food":{"tags":{"name":"M&S Simply Food","shop":"convenience"},"name":"M&S Simply Food","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mace":{"tags":{"name":"Mace","shop":"convenience"},"name":"Mace","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Magazin":{"tags":{"name":"Magazin","shop":"convenience"},"name":"Magazin","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Magazin Mixt":{"tags":{"name":"Magazin Mixt","shop":"convenience"},"name":"Magazin Mixt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Magazin Non-Stop":{"tags":{"name":"Magazin Non-Stop","shop":"convenience"},"name":"Magazin Non-Stop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Magazin mixt":{"tags":{"name":"Magazin mixt","shop":"convenience"},"name":"Magazin mixt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Maxikiosco":{"tags":{"name":"Maxikiosco","shop":"convenience"},"name":"Maxikiosco","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Małpka Express":{"tags":{"name":"Małpka Express","shop":"convenience"},"name":"Małpka Express","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Migrolino":{"tags":{"name":"Migrolino","shop":"convenience"},"name":"Migrolino","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini ABC":{"tags":{"name":"Mini ABC","shop":"convenience"},"name":"Mini ABC","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Mart":{"tags":{"name":"Mini Mart","shop":"convenience"},"name":"Mini Mart","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Minimarket":{"tags":{"name":"Minimarket","shop":"convenience"},"name":"Minimarket","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Minimercado":{"tags":{"name":"Minimercado","shop":"convenience"},"name":"Minimercado","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mlin i pekare":{"tags":{"name":"Mlin i pekare","shop":"convenience"},"name":"Mlin i pekare","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Nasz Sklep":{"tags":{"name":"Nasz Sklep","shop":"convenience"},"name":"Nasz Sklep","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Nisa":{"tags":{"name":"Nisa","shop":"convenience"},"name":"Nisa","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/OK-Mart":{"tags":{"name":"OK-Mart","shop":"convenience"},"name":"OK-Mart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/OK便利商店":{"tags":{"name":"OK便利商店","shop":"convenience"},"name":"OK便利商店","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/OK便利店 Circle K":{"tags":{"name":"OK便利店 Circle K","shop":"convenience"},"name":"OK便利店 Circle K","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Odido":{"tags":{"name":"Odido","shop":"convenience"},"name":"Odido","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/On The Run":{"tags":{"name":"On The Run","shop":"convenience"},"name":"On The Run","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/On the Run":{"tags":{"name":"On the Run","shop":"convenience"},"name":"On the Run","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Oxxo":{"tags":{"name":"Oxxo","shop":"convenience"},"name":"Oxxo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Parduotuvė":{"tags":{"name":"Parduotuvė","shop":"convenience"},"name":"Parduotuvė","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Plaid Pantry":{"tags":{"name":"Plaid Pantry","shop":"convenience"},"name":"Plaid Pantry","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Potraviny":{"tags":{"name":"Potraviny","shop":"convenience"},"name":"Potraviny","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Prehrana":{"tags":{"name":"Prehrana","shop":"convenience"},"name":"Prehrana","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Premier":{"tags":{"name":"Premier","shop":"convenience"},"name":"Premier","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Proxi":{"tags":{"name":"Proxi","shop":"convenience"},"name":"Proxi","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Proxy":{"tags":{"name":"Proxy","shop":"convenience"},"name":"Proxy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Pulperia":{"tags":{"name":"Pulperia","shop":"convenience"},"name":"Pulperia","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sale":{"tags":{"name":"Sale","shop":"convenience"},"name":"Sale","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sari-sari Store":{"tags":{"name":"Sari-sari Store","shop":"convenience"},"name":"Sari-sari Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Select":{"tags":{"name":"Select","shop":"convenience"},"name":"Select","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Shell Select":{"tags":{"name":"Shell Select","shop":"convenience"},"name":"Shell Select","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Shop & Go":{"tags":{"name":"Shop & Go","shop":"convenience"},"name":"Shop & Go","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Siwa":{"tags":{"name":"Siwa","shop":"convenience"},"name":"Siwa","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Smíšené zboží":{"tags":{"name":"Smíšené zboží","shop":"convenience"},"name":"Smíšené zboží","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Spätkauf":{"tags":{"name":"Spätkauf","shop":"convenience"},"name":"Spätkauf","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Stores":{"tags":{"name":"Stores","shop":"convenience"},"name":"Stores","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Stripes":{"tags":{"name":"Stripes","shop":"convenience"},"name":"Stripes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Studenac":{"tags":{"name":"Studenac","shop":"convenience"},"name":"Studenac","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sunkus":{"tags":{"name":"Sunkus","shop":"convenience"},"name":"Sunkus","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Słoneczko":{"tags":{"name":"Słoneczko","shop":"convenience"},"name":"Słoneczko","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Tom Market 89":{"tags":{"name":"Tom Market 89","shop":"convenience"},"name":"Tom Market 89","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/United Dairy Farmers":{"tags":{"name":"United Dairy Farmers","shop":"convenience"},"name":"United Dairy Farmers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Vegyesbolt":{"tags":{"name":"Vegyesbolt","shop":"convenience"},"name":"Vegyesbolt","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Vival":{"tags":{"name":"Vival","shop":"convenience"},"name":"Vival","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Wawa":{"tags":{"name":"Wawa","shop":"convenience"},"name":"Wawa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Weltladen":{"tags":{"name":"Weltladen","shop":"convenience"},"name":"Weltladen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/abc":{"tags":{"name":"abc","shop":"convenience"},"name":"abc","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ampm":{"tags":{"name":"ampm","shop":"convenience"},"name":"ampm","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/best-one":{"tags":{"name":"best-one","shop":"convenience"},"name":"best-one","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/odido":{"tags":{"name":"odido","shop":"convenience"},"name":"odido","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Élelmiszer":{"tags":{"name":"Élelmiszer","shop":"convenience"},"name":"Élelmiszer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Élelmiszerbolt":{"tags":{"name":"Élelmiszerbolt","shop":"convenience"},"name":"Élelmiszerbolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Żabka":{"tags":{"name":"Żabka","shop":"convenience"},"name":"Żabka","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Žabka":{"tags":{"name":"Žabka","shop":"convenience"},"name":"Žabka","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Августина":{"tags":{"name":"Августина","shop":"convenience"},"name":"Августина","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Авоська":{"tags":{"name":"Авоська","shop":"convenience"},"name":"Авоська","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Агрокомплекс":{"tags":{"name":"Агрокомплекс","shop":"convenience"},"name":"Агрокомплекс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Альянс":{"tags":{"name":"Альянс","shop":"convenience"},"name":"Альянс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Апельсин":{"tags":{"name":"Апельсин","shop":"convenience"},"name":"Апельсин","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Ассорти":{"tags":{"name":"Ассорти","shop":"convenience"},"name":"Ассорти","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Белорусские продукты":{"tags":{"name":"Белорусские продукты","shop":"convenience"},"name":"Белорусские продукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Берёзка":{"tags":{"name":"Берёзка","shop":"convenience"},"name":"Берёзка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Везунчик":{"tags":{"name":"Везунчик","shop":"convenience"},"name":"Везунчик","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Весна":{"tags":{"name":"Весна","shop":"convenience"},"name":"Весна","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Ветеран":{"tags":{"name":"Ветеран","shop":"convenience"},"name":"Ветеран","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Визит":{"tags":{"name":"Визит","shop":"convenience"},"name":"Визит","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Виктория":{"tags":{"name":"Виктория","shop":"convenience"},"name":"Виктория","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ВкусВилл":{"tags":{"name":"ВкусВилл","shop":"convenience"},"name":"ВкусВилл","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Гастроном":{"tags":{"name":"Гастроном","shop":"convenience"},"name":"Гастроном","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Гермес":{"tags":{"name":"Гермес","shop":"convenience"},"name":"Гермес","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Гурман":{"tags":{"name":"Гурман","shop":"convenience"},"name":"Гурман","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Домашний":{"tags":{"name":"Домашний","shop":"convenience"},"name":"Домашний","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Елена":{"tags":{"name":"Елена","shop":"convenience"},"name":"Елена","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Ермолино":{"tags":{"name":"Ермолино","shop":"convenience"},"name":"Ермолино","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Калинка":{"tags":{"name":"Калинка","shop":"convenience"},"name":"Калинка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кировский":{"tags":{"name":"Кировский","shop":"convenience"},"name":"Кировский","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Колобок":{"tags":{"name":"Колобок","shop":"convenience"},"name":"Колобок","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Колосок":{"tags":{"name":"Колосок","shop":"convenience"},"name":"Колосок","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Копеечка":{"tags":{"name":"Копеечка","shop":"convenience"},"name":"Копеечка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Копейка":{"tags":{"name":"Копейка","shop":"convenience"},"name":"Копейка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Корзинка":{"tags":{"name":"Корзинка","shop":"convenience"},"name":"Корзинка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Крамниця":{"tags":{"name":"Крамниця","shop":"convenience"},"name":"Крамниця","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кристалл":{"tags":{"name":"Кристалл","shop":"convenience"},"name":"Кристалл","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кулинария":{"tags":{"name":"Кулинария","shop":"convenience"},"name":"Кулинария","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Купец":{"tags":{"name":"Купец","shop":"convenience"},"name":"Купец","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Ласточка":{"tags":{"name":"Ласточка","shop":"convenience"},"name":"Ласточка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Лидер":{"tags":{"name":"Лидер","shop":"convenience"},"name":"Лидер","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Любимый":{"tags":{"name":"Любимый","shop":"convenience"},"name":"Любимый","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Люкс":{"tags":{"name":"Люкс","shop":"convenience"},"name":"Люкс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Магазин при АЗС":{"tags":{"name":"Магазин при АЗС","shop":"convenience"},"name":"Магазин при АЗС","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Мария-Ра":{"tags":{"name":"Мария-Ра","shop":"convenience"},"name":"Мария-Ра","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Маяк":{"tags":{"name":"Маяк","shop":"convenience"},"name":"Маяк","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Меркурий":{"tags":{"name":"Меркурий","shop":"convenience"},"name":"Меркурий","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Мечта":{"tags":{"name":"Мечта","shop":"convenience"},"name":"Мечта","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Минимаркет":{"tags":{"name":"Минимаркет","shop":"convenience"},"name":"Минимаркет","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Мираж":{"tags":{"name":"Мираж","shop":"convenience"},"name":"Мираж","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Надежда":{"tags":{"name":"Надежда","shop":"convenience"},"name":"Надежда","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Ника":{"tags":{"name":"Ника","shop":"convenience"},"name":"Ника","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Оазис":{"tags":{"name":"Оазис","shop":"convenience"},"name":"Оазис","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Олимп":{"tags":{"name":"Олимп","shop":"convenience"},"name":"Олимп","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Подсолнух":{"tags":{"name":"Подсолнух","shop":"convenience"},"name":"Подсолнух","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Престиж":{"tags":{"name":"Престиж","shop":"convenience"},"name":"Престиж","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукти":{"tags":{"name":"Продукти","shop":"convenience"},"name":"Продукти","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продуктовый":{"tags":{"name":"Продуктовый","shop":"convenience"},"name":"Продуктовый","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продуктовый магазин":{"tags":{"name":"Продуктовый магазин","shop":"convenience"},"name":"Продуктовый магазин","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукты":{"tags":{"name":"Продукты","shop":"convenience"},"name":"Продукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукты 24":{"tags":{"name":"Продукты 24","shop":"convenience"},"name":"Продукты 24","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Радуга":{"tags":{"name":"Радуга","shop":"convenience"},"name":"Радуга","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Родны кут":{"tags":{"name":"Родны кут","shop":"convenience"},"name":"Родны кут","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Ромашка":{"tags":{"name":"Ромашка","shop":"convenience"},"name":"Ромашка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Русь":{"tags":{"name":"Русь","shop":"convenience"},"name":"Русь","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Светлана":{"tags":{"name":"Светлана","shop":"convenience"},"name":"Светлана","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Смак":{"tags":{"name":"Смак","shop":"convenience"},"name":"Смак","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Солнечный":{"tags":{"name":"Солнечный","shop":"convenience"},"name":"Солнечный","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Татьяна":{"tags":{"name":"Татьяна","shop":"convenience"},"name":"Татьяна","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Тройка":{"tags":{"name":"Тройка","shop":"convenience"},"name":"Тройка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/У Палыча":{"tags":{"name":"У Палыча","shop":"convenience"},"name":"У Палыча","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Универсам":{"tags":{"name":"Универсам","shop":"convenience"},"name":"Универсам","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Фортуна":{"tags":{"name":"Фортуна","shop":"convenience"},"name":"Фортуна","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Хороший":{"tags":{"name":"Хороший","shop":"convenience"},"name":"Хороший","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Центральный":{"tags":{"name":"Центральный","shop":"convenience"},"name":"Центральный","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Чайка":{"tags":{"name":"Чайка","shop":"convenience"},"name":"Чайка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Шанс":{"tags":{"name":"Шанс","shop":"convenience"},"name":"Шанс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Эконом":{"tags":{"name":"Эконом","shop":"convenience"},"name":"Эконом","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Юбилейный":{"tags":{"name":"Юбилейный","shop":"convenience"},"name":"Юбилейный","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Юлия":{"tags":{"name":"Юлия","shop":"convenience"},"name":"Юлия","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/продукты":{"tags":{"name":"продукты","shop":"convenience"},"name":"продукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/მარკეტი":{"tags":{"name":"მარკეტი","shop":"convenience"},"name":"მარკეტი","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/サンクス":{"tags":{"name":"サンクス","name:en":"sunkus","shop":"convenience"},"name":"サンクス","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/スリーエフ":{"tags":{"name":"スリーエフ","shop":"convenience"},"name":"スリーエフ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セイコーマート":{"tags":{"name":"セイコーマート","shop":"convenience"},"name":"セイコーマート","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セーブオン":{"tags":{"name":"セーブオン","shop":"convenience"},"name":"セーブオン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/デイリーヤマザキ":{"tags":{"name":"デイリーヤマザキ","shop":"convenience"},"name":"デイリーヤマザキ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ファミリーマート":{"tags":{"name":"ファミリーマート","name:en":"FamilyMart","shop":"convenience"},"name":"ファミリーマート","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ポプラ":{"tags":{"name":"ポプラ","shop":"convenience"},"name":"ポプラ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ミニストップ":{"tags":{"name":"ミニストップ","name:en":"MINISTOP","shop":"convenience"},"name":"ミニストップ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ヤマザキショップ":{"tags":{"name":"ヤマザキショップ","shop":"convenience"},"name":"ヤマザキショップ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソン":{"tags":{"name":"ローソン","name:en":"LAWSON","shop":"convenience"},"name":"ローソン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソンストア100":{"tags":{"name":"ローソンストア100","shop":"convenience"},"name":"ローソンストア100","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/全家":{"tags":{"name":"全家","shop":"convenience"},"name":"全家","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/全家便利商店":{"tags":{"name":"全家便利商店","shop":"convenience"},"name":"全家便利商店","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/萊爾富":{"tags":{"name":"萊爾富","shop":"convenience"},"name":"萊爾富","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/세븐일레븐":{"tags":{"name":"세븐일레븐","shop":"convenience"},"name":"세븐일레븐","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/copyshop/FedEx Office":{"tags":{"name":"FedEx Office","shop":"copyshop"},"name":"FedEx Office","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/copyshop/FedEx Office Print and Ship Center":{"tags":{"name":"FedEx Office Print and Ship Center","shop":"copyshop"},"name":"FedEx Office Print and Ship Center","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Douglas":{"tags":{"name":"Douglas","shop":"cosmetics"},"name":"Douglas","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Lush":{"tags":{"name":"Lush","shop":"cosmetics"},"name":"Lush","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Marionnaud":{"tags":{"name":"Marionnaud","shop":"cosmetics"},"name":"Marionnaud","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Sephora":{"tags":{"name":"Sephora","shop":"cosmetics"},"name":"Sephora","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/The Body Shop":{"tags":{"name":"The Body Shop","shop":"cosmetics"},"name":"The Body Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Л'Этуаль":{"tags":{"name":"Л'Этуаль","shop":"cosmetics"},"name":"Л'Этуаль","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Магнит косметик":{"tags":{"name":"Магнит косметик","shop":"cosmetics"},"name":"Магнит косметик","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Магнит-Косметик":{"tags":{"name":"Магнит-Косметик","shop":"cosmetics"},"name":"Магнит-Косметик","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/cosmetics/Подружка":{"tags":{"name":"Подружка","shop":"cosmetics"},"name":"Подружка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/craft/Hobby Lobby":{"tags":{"name":"Hobby Lobby","shop":"craft"},"name":"Hobby Lobby","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/craft/Michaels":{"tags":{"name":"Michaels","shop":"craft"},"name":"Michaels","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Argos":{"tags":{"name":"Argos","shop":"department_store"},"name":"Argos","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Bed Bath & Beyond":{"tags":{"name":"Bed Bath & Beyond","shop":"department_store"},"name":"Bed Bath & Beyond","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Big Lots":{"tags":{"name":"Big Lots","shop":"department_store"},"name":"Big Lots","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Canadian Tire":{"tags":{"name":"Canadian Tire","shop":"department_store"},"name":"Canadian Tire","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Coppel":{"tags":{"name":"Coppel","shop":"department_store"},"name":"Coppel","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Dillard's":{"tags":{"name":"Dillard's","shop":"department_store"},"name":"Dillard's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/El Corte Inglés":{"tags":{"name":"El Corte Inglés","shop":"department_store"},"name":"El Corte Inglés","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/HEMA":{"tags":{"name":"HEMA","shop":"department_store"},"name":"HEMA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Harvey Norman":{"tags":{"name":"Harvey Norman","shop":"department_store"},"name":"Harvey Norman","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Lojas Americanas":{"tags":{"name":"Lojas Americanas","shop":"department_store"},"name":"Lojas Americanas","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Myer":{"tags":{"name":"Myer","shop":"department_store"},"name":"Myer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Nordstrom":{"tags":{"name":"Nordstrom","shop":"department_store"},"name":"Nordstrom","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Shopko":{"tags":{"name":"Shopko","shop":"department_store"},"name":"Shopko","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/The Warehouse":{"tags":{"name":"The Warehouse","shop":"department_store"},"name":"The Warehouse","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Универмаг":{"tags":{"name":"Универмаг","shop":"department_store"},"name":"Универмаг","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Ace Hardware":{"tags":{"name":"Ace Hardware","shop":"doityourself"},"name":"Ace Hardware","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/B&Q":{"tags":{"name":"B&Q","shop":"doityourself"},"name":"B&Q","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bauhaus":{"tags":{"name":"Bauhaus","shop":"doityourself"},"name":"Bauhaus","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Biltema":{"tags":{"name":"Biltema","shop":"doityourself"},"name":"Biltema","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Brico":{"tags":{"name":"Brico","shop":"doityourself"},"name":"Brico","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bricomarché":{"tags":{"name":"Bricomarché","shop":"doityourself"},"name":"Bricomarché","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bricorama":{"tags":{"name":"Bricorama","shop":"doityourself"},"name":"Bricorama","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bunnings Warehouse":{"tags":{"name":"Bunnings Warehouse","shop":"doityourself"},"name":"Bunnings Warehouse","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Castorama":{"tags":{"name":"Castorama","shop":"doityourself"},"name":"Castorama","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Easy":{"tags":{"name":"Easy","shop":"doityourself"},"name":"Easy","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Gamma":{"tags":{"name":"Gamma","shop":"doityourself"},"name":"Gamma","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Globus Baumarkt":{"tags":{"name":"Globus Baumarkt","shop":"doityourself"},"name":"Globus Baumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hagebaumarkt":{"tags":{"name":"Hagebaumarkt","shop":"doityourself"},"name":"Hagebaumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hellweg":{"tags":{"name":"Hellweg","shop":"doityourself"},"name":"Hellweg","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Home Depot":{"tags":{"name":"Home Depot","shop":"doityourself"},"name":"Home Depot","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Home Hardware":{"tags":{"name":"Home Hardware","shop":"doityourself"},"name":"Home Hardware","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Homebase":{"tags":{"name":"Homebase","shop":"doityourself"},"name":"Homebase","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hornbach":{"tags":{"name":"Hornbach","shop":"doityourself"},"name":"Hornbach","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hubo":{"tags":{"name":"Hubo","shop":"doityourself"},"name":"Hubo","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Karwei":{"tags":{"name":"Karwei","shop":"doityourself"},"name":"Karwei","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lagerhaus":{"tags":{"name":"Lagerhaus","shop":"doityourself"},"name":"Lagerhaus","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Leroy Merlin":{"tags":{"name":"Leroy Merlin","shop":"doityourself"},"name":"Leroy Merlin","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lowe's":{"tags":{"name":"Lowe's","shop":"doityourself"},"name":"Lowe's","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lowes":{"tags":{"name":"Lowes","shop":"doityourself"},"name":"Lowes","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Menards":{"tags":{"name":"Menards","shop":"doityourself"},"name":"Menards","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Mr Bricolage":{"tags":{"name":"Mr Bricolage","shop":"doityourself"},"name":"Mr Bricolage","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Mr.Bricolage":{"tags":{"name":"Mr.Bricolage","shop":"doityourself"},"name":"Mr.Bricolage","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/OBI":{"tags":{"name":"OBI","shop":"doityourself"},"name":"OBI","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Point P":{"tags":{"name":"Point P","shop":"doityourself"},"name":"Point P","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Praktiker":{"tags":{"name":"Praktiker","shop":"doityourself"},"name":"Praktiker","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Praxis":{"tags":{"name":"Praxis","shop":"doityourself"},"name":"Praxis","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Rona":{"tags":{"name":"Rona","shop":"doityourself"},"name":"Rona","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Screwfix":{"tags":{"name":"Screwfix","shop":"doityourself"},"name":"Screwfix","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Sonderpreis Baumarkt":{"tags":{"name":"Sonderpreis Baumarkt","shop":"doityourself"},"name":"Sonderpreis Baumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Tekzen":{"tags":{"name":"Tekzen","shop":"doityourself"},"name":"Tekzen","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Toom Baumarkt":{"tags":{"name":"Toom Baumarkt","shop":"doityourself"},"name":"Toom Baumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Weldom":{"tags":{"name":"Weldom","shop":"doityourself"},"name":"Weldom","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Wickes":{"tags":{"name":"Wickes","shop":"doityourself"},"name":"Wickes","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Леруа Мерлен":{"tags":{"name":"Леруа Мерлен","shop":"doityourself"},"name":"Леруа Мерлен","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Мастер":{"tags":{"name":"Мастер","shop":"doityourself"},"name":"Мастер","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Строитель":{"tags":{"name":"Строитель","shop":"doityourself"},"name":"Строитель","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Стройматериалы":{"tags":{"name":"Стройматериалы","shop":"doityourself"},"name":"Стройматериалы","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/カインズホーム":{"tags":{"name":"カインズホーム","shop":"doityourself"},"name":"カインズホーム","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/コメリ":{"tags":{"name":"コメリ","shop":"doityourself"},"name":"コメリ","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/コーナン":{"tags":{"name":"コーナン","shop":"doityourself"},"name":"コーナン","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/dry_cleaning/Cleaners":{"tags":{"name":"Cleaners","shop":"dry_cleaning"},"name":"Cleaners","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/dry_cleaning/Pressing":{"tags":{"name":"Pressing","shop":"dry_cleaning"},"name":"Pressing","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/dry_cleaning/Диана":{"tags":{"name":"Диана","shop":"dry_cleaning"},"name":"Диана","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/dry_cleaning/Химчистка":{"tags":{"name":"Химчистка","shop":"dry_cleaning"},"name":"Химчистка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/dry_cleaning/ホワイト急便":{"tags":{"name":"ホワイト急便","shop":"dry_cleaning"},"name":"ホワイト急便","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/BCC":{"tags":{"name":"BCC","shop":"electronics"},"name":"BCC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Batteries Plus Bulbs":{"tags":{"name":"Batteries Plus Bulbs","shop":"electronics"},"name":"Batteries Plus Bulbs","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Boulanger":{"tags":{"name":"Boulanger","shop":"electronics"},"name":"Boulanger","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Currys":{"tags":{"name":"Currys","shop":"electronics"},"name":"Currys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Currys PC World":{"tags":{"name":"Currys PC World","shop":"electronics"},"name":"Currys PC World","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Darty":{"tags":{"name":"Darty","shop":"electronics"},"name":"Darty","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Elektra":{"tags":{"name":"Elektra","shop":"electronics"},"name":"Elektra","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Elgiganten":{"tags":{"name":"Elgiganten","shop":"electronics"},"name":"Elgiganten","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Euronics":{"tags":{"name":"Euronics","shop":"electronics"},"name":"Euronics","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Expert":{"tags":{"name":"Expert","shop":"electronics"},"name":"Expert","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Hartlauer":{"tags":{"name":"Hartlauer","shop":"electronics"},"name":"Hartlauer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Interdiscount":{"tags":{"name":"Interdiscount","shop":"electronics"},"name":"Interdiscount","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/La Curacao":{"tags":{"name":"La Curacao","shop":"electronics"},"name":"La Curacao","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Maplin":{"tags":{"name":"Maplin","shop":"electronics"},"name":"Maplin","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Media Expert":{"tags":{"name":"Media Expert","shop":"electronics"},"name":"Media Expert","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Musimundo":{"tags":{"name":"Musimundo","shop":"electronics"},"name":"Musimundo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Neonet":{"tags":{"name":"Neonet","shop":"electronics"},"name":"Neonet","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/RTV Euro AGD":{"tags":{"name":"RTV Euro AGD","shop":"electronics"},"name":"RTV Euro AGD","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Rogers":{"tags":{"name":"Rogers","shop":"electronics"},"name":"Rogers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Samsung":{"tags":{"name":"Samsung","shop":"electronics"},"name":"Samsung","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Saturn":{"tags":{"name":"Saturn","shop":"electronics"},"name":"Saturn","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Sony":{"tags":{"name":"Sony","shop":"electronics"},"name":"Sony","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/The Source":{"tags":{"name":"The Source","shop":"electronics"},"name":"The Source","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Unieuro":{"tags":{"name":"Unieuro","shop":"electronics"},"name":"Unieuro","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/М.Видео":{"tags":{"name":"М.Видео","shop":"electronics"},"name":"М.Видео","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Фокстрот":{"tags":{"name":"Фокстрот","shop":"electronics"},"name":"Фокстрот","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Эксперт":{"tags":{"name":"Эксперт","shop":"electronics"},"name":"Эксперт","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Эльдорадо":{"tags":{"name":"Эльдорадо","shop":"electronics"},"name":"Эльдорадо","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/エディオン":{"tags":{"name":"エディオン","shop":"electronics"},"name":"エディオン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/ケーズデンキ":{"tags":{"name":"ケーズデンキ","shop":"electronics"},"name":"ケーズデンキ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/コジマ":{"tags":{"name":"コジマ","shop":"electronics"},"name":"コジマ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/ヤマダ電機":{"tags":{"name":"ヤマダ電機","shop":"electronics"},"name":"ヤマダ電機","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/全國電子":{"tags":{"name":"全國電子","shop":"electronics"},"name":"全國電子","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/燦坤3C":{"tags":{"name":"燦坤3C","shop":"electronics"},"name":"燦坤3C","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/erotic/Orion":{"tags":{"name":"Orion","shop":"erotic"},"name":"Orion","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/fabric/Ткани":{"tags":{"name":"Ткани","shop":"fabric"},"name":"Ткани","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/farm/Hofladen":{"tags":{"name":"Hofladen","shop":"farm"},"name":"Hofladen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Blume 2000":{"tags":{"name":"Blume 2000","shop":"florist"},"name":"Blume 2000","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Blumen Risse":{"tags":{"name":"Blumen Risse","shop":"florist"},"name":"Blumen Risse","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Fleuriste":{"tags":{"name":"Fleuriste","shop":"florist"},"name":"Fleuriste","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Interflora":{"tags":{"name":"Interflora","shop":"florist"},"name":"Interflora","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Monceau Fleurs":{"tags":{"name":"Monceau Fleurs","shop":"florist"},"name":"Monceau Fleurs","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Virágbolt":{"tags":{"name":"Virágbolt","shop":"florist"},"name":"Virágbolt","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Квіти":{"tags":{"name":"Квіти","shop":"florist"},"name":"Квіти","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Цветочный магазин":{"tags":{"name":"Цветочный магазин","shop":"florist"},"name":"Цветочный магазин","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/florist/Цветы":{"tags":{"name":"Цветы","shop":"florist"},"name":"Цветы","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/frame/rumah penduduk":{"tags":{"name":"rumah penduduk","shop":"frame"},"name":"rumah penduduk","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/funeral_directors/Funeraria":{"tags":{"name":"Funeraria","shop":"funeral_directors"},"name":"Funeraria","icon":"cemetery","geometry":["point","area"],"fields":["name","operator","address","building_area","religion","denomination"],"suggestion":true},"shop/funeral_directors/The Co-operative Funeralcare":{"tags":{"name":"The Co-operative Funeralcare","shop":"funeral_directors"},"name":"The Co-operative Funeralcare","icon":"cemetery","geometry":["point","area"],"fields":["name","operator","address","building_area","religion","denomination"],"suggestion":true},"shop/funeral_directors/Ритуальные услуги":{"tags":{"name":"Ритуальные услуги","shop":"funeral_directors"},"name":"Ритуальные услуги","icon":"cemetery","geometry":["point","area"],"fields":["name","operator","address","building_area","religion","denomination"],"suggestion":true},"shop/furniture/Aaron's":{"tags":{"name":"Aaron's","shop":"furniture"},"name":"Aaron's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Black Red White":{"tags":{"name":"Black Red White","shop":"furniture"},"name":"Black Red White","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Bodzio":{"tags":{"name":"Bodzio","shop":"furniture"},"name":"Bodzio","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/But":{"tags":{"name":"But","shop":"furniture"},"name":"But","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Conforama":{"tags":{"name":"Conforama","shop":"furniture"},"name":"Conforama","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/DFS":{"tags":{"name":"DFS","shop":"furniture"},"name":"DFS","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Fly":{"tags":{"name":"Fly","shop":"furniture"},"name":"Fly","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Harveys":{"tags":{"name":"Harveys","shop":"furniture"},"name":"Harveys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/IKEA":{"tags":{"name":"IKEA","shop":"furniture"},"name":"IKEA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/JYSK":{"tags":{"name":"JYSK","shop":"furniture"},"name":"JYSK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Kwantum":{"tags":{"name":"Kwantum","shop":"furniture"},"name":"Kwantum","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Leen Bakker":{"tags":{"name":"Leen Bakker","shop":"furniture"},"name":"Leen Bakker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Pier 1 Imports":{"tags":{"name":"Pier 1 Imports","shop":"furniture"},"name":"Pier 1 Imports","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Roller":{"tags":{"name":"Roller","shop":"furniture"},"name":"Roller","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/The Brick":{"tags":{"name":"The Brick","shop":"furniture"},"name":"The Brick","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Меблі":{"tags":{"name":"Меблі","shop":"furniture"},"name":"Меблі","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/ニトリ":{"tags":{"name":"ニトリ","shop":"furniture"},"name":"ニトリ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/garden_centre/Dehner":{"tags":{"name":"Dehner","shop":"garden_centre"},"name":"Dehner","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/garden_centre/Gamm Vert":{"tags":{"name":"Gamm Vert","shop":"garden_centre"},"name":"Gamm Vert","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/garden_centre/Jardiland":{"tags":{"name":"Jardiland","shop":"garden_centre"},"name":"Jardiland","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/garden_centre/Point Vert":{"tags":{"name":"Point Vert","shop":"garden_centre"},"name":"Point Vert","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/garden_centre/Welkoop":{"tags":{"name":"Welkoop","shop":"garden_centre"},"name":"Welkoop","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/garden_centre/Семена":{"tags":{"name":"Семена","shop":"garden_centre"},"name":"Семена","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/gift/Card Factory":{"tags":{"name":"Card Factory","shop":"gift"},"name":"Card Factory","icon":"gift","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/gift/Hallmark":{"tags":{"name":"Hallmark","shop":"gift"},"name":"Hallmark","icon":"gift","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/gift/Подарки":{"tags":{"name":"Подарки","shop":"gift"},"name":"Подарки","icon":"gift","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/greengrocer/Frutería":{"tags":{"name":"Frutería","shop":"greengrocer"},"name":"Frutería","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/greengrocer/Овощи и фрукты":{"tags":{"name":"Овощи и фрукты","shop":"greengrocer"},"name":"Овощи и фрукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Barbershop":{"tags":{"name":"Barbershop","shop":"hairdresser"},"name":"Barbershop","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Berber":{"tags":{"name":"Berber","shop":"hairdresser"},"name":"Berber","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Cost Cutters":{"tags":{"name":"Cost Cutters","shop":"hairdresser"},"name":"Cost Cutters","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Fantastic Sams":{"tags":{"name":"Fantastic Sams","shop":"hairdresser"},"name":"Fantastic Sams","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Figaro":{"tags":{"name":"Figaro","shop":"hairdresser"},"name":"Figaro","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/First Choice Haircutters":{"tags":{"name":"First Choice Haircutters","shop":"hairdresser"},"name":"First Choice Haircutters","icon":"hairdresser","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Frizerie":{"tags":{"name":"Frizerie","shop":"hairdresser"},"name":"Frizerie","icon":"hairdresser","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Haarmonie":{"tags":{"name":"Haarmonie","shop":"hairdresser"},"name":"Haarmonie","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Haarscharf":{"tags":{"name":"Haarscharf","shop":"hairdresser"},"name":"Haarscharf","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Hair Cuttery":{"tags":{"name":"Hair Cuttery","shop":"hairdresser"},"name":"Hair Cuttery","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Hairkiller":{"tags":{"name":"Hairkiller","shop":"hairdresser"},"name":"Hairkiller","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Jean Louis David":{"tags":{"name":"Jean Louis David","shop":"hairdresser"},"name":"Jean Louis David","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Jean-Louis David":{"tags":{"name":"Jean-Louis David","shop":"hairdresser"},"name":"Jean-Louis David","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Klier":{"tags":{"name":"Klier","shop":"hairdresser"},"name":"Klier","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Klipp":{"tags":{"name":"Klipp","shop":"hairdresser"},"name":"Klipp","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Le Salon":{"tags":{"name":"Le Salon","shop":"hairdresser"},"name":"Le Salon","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Marco Aldany":{"tags":{"name":"Marco Aldany","shop":"hairdresser"},"name":"Marco Aldany","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Peluquería":{"tags":{"name":"Peluquería","shop":"hairdresser"},"name":"Peluquería","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Salon":{"tags":{"name":"Salon","shop":"hairdresser"},"name":"Salon","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Salon fryzjerski":{"tags":{"name":"Salon fryzjerski","shop":"hairdresser"},"name":"Salon fryzjerski","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Sport Clips":{"tags":{"name":"Sport Clips","shop":"hairdresser"},"name":"Sport Clips","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Super Cuts":{"tags":{"name":"Super Cuts","shop":"hairdresser"},"name":"Super Cuts","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Supercuts":{"tags":{"name":"Supercuts","shop":"hairdresser"},"name":"Supercuts","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Tchip":{"tags":{"name":"Tchip","shop":"hairdresser"},"name":"Tchip","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/The Barber Shop":{"tags":{"name":"The Barber Shop","shop":"hairdresser"},"name":"The Barber Shop","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Toni & Guy":{"tags":{"name":"Toni & Guy","shop":"hairdresser"},"name":"Toni & Guy","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Top Hair":{"tags":{"name":"Top Hair","shop":"hairdresser"},"name":"Top Hair","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Локон":{"tags":{"name":"Локон","shop":"hairdresser"},"name":"Локон","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Парикмахерская":{"tags":{"name":"Парикмахерская","shop":"hairdresser"},"name":"Парикмахерская","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Перукарня":{"tags":{"name":"Перукарня","shop":"hairdresser"},"name":"Перукарня","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Салон красоты":{"tags":{"name":"Салон красоты","shop":"hairdresser"},"name":"Салон красоты","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Стиль":{"tags":{"name":"Стиль","shop":"hairdresser"},"name":"Стиль","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Шарм":{"tags":{"name":"Шарм","shop":"hairdresser"},"name":"Шарм","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/حلاق":{"tags":{"name":"حلاق","shop":"hairdresser"},"name":"حلاق","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/1000 мелочей":{"tags":{"name":"1000 мелочей","shop":"hardware"},"name":"1000 мелочей","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Ferretería":{"tags":{"name":"Ferretería","shop":"hardware"},"name":"Ferretería","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Harbor Freight Tools":{"tags":{"name":"Harbor Freight Tools","shop":"hardware"},"name":"Harbor Freight Tools","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Quincaillerie":{"tags":{"name":"Quincaillerie","shop":"hardware"},"name":"Quincaillerie","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/True Value":{"tags":{"name":"True Value","shop":"hardware"},"name":"True Value","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Würth":{"tags":{"name":"Würth","shop":"hardware"},"name":"Würth","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Промтовары":{"tags":{"name":"Промтовары","shop":"hardware"},"name":"Промтовары","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Сантехника":{"tags":{"name":"Сантехника","shop":"hardware"},"name":"Сантехника","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Товары для дома":{"tags":{"name":"Товары для дома","shop":"hardware"},"name":"Товары для дома","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Хозтовары":{"tags":{"name":"Хозтовары","shop":"hardware"},"name":"Хозтовары","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hearing_aids/Amplifon":{"tags":{"name":"Amplifon","shop":"hearing_aids"},"name":"Amplifon","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hearing_aids/Geers":{"tags":{"name":"Geers","shop":"hearing_aids"},"name":"Geers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hearing_aids/Kind Hörgeräte":{"tags":{"name":"Kind Hörgeräte","shop":"hearing_aids"},"name":"Kind Hörgeräte","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hearing_aids/amplifon":{"tags":{"name":"amplifon","shop":"hearing_aids"},"name":"amplifon","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/hifi/Bang & Olufsen":{"tags":{"name":"Bang & Olufsen","shop":"hifi"},"name":"Bang & Olufsen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/houseware/Blokker":{"tags":{"name":"Blokker","shop":"houseware"},"name":"Blokker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/houseware/Marskramer":{"tags":{"name":"Marskramer","shop":"houseware"},"name":"Marskramer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/houseware/Xenos":{"tags":{"name":"Xenos","shop":"houseware"},"name":"Xenos","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/interior_decoration/Casa":{"tags":{"name":"Casa","shop":"interior_decoration"},"name":"Casa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/interior_decoration/Depot":{"tags":{"name":"Depot","shop":"interior_decoration"},"name":"Depot","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/585":{"tags":{"name":"585","shop":"jewelry"},"name":"585","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Apart":{"tags":{"name":"Apart","shop":"jewelry"},"name":"Apart","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Christ":{"tags":{"name":"Christ","shop":"jewelry"},"name":"Christ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Claire's":{"tags":{"name":"Claire's","shop":"jewelry"},"name":"Claire's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Ernest Jones":{"tags":{"name":"Ernest Jones","shop":"jewelry"},"name":"Ernest Jones","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/H Samuel":{"tags":{"name":"H Samuel","shop":"jewelry"},"name":"H Samuel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/James Avery Jewelry":{"tags":{"name":"James Avery Jewelry","shop":"jewelry"},"name":"James Avery Jewelry","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Julien d'Orcel":{"tags":{"name":"Julien d'Orcel","shop":"jewelry"},"name":"Julien d'Orcel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Kay Jewelers":{"tags":{"name":"Kay Jewelers","shop":"jewelry"},"name":"Kay Jewelers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Pandora":{"tags":{"name":"Pandora","shop":"jewelry"},"name":"Pandora","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Swarovski":{"tags":{"name":"Swarovski","shop":"jewelry"},"name":"Swarovski","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Адамас":{"tags":{"name":"Адамас","shop":"jewelry"},"name":"Адамас","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Золото":{"tags":{"name":"Золото","shop":"jewelry"},"name":"Золото","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/KIOS":{"tags":{"name":"KIOS","shop":"kiosk"},"name":"KIOS","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Kiosco":{"tags":{"name":"Kiosco","shop":"kiosk"},"name":"Kiosco","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Kiosk":{"tags":{"name":"Kiosk","shop":"kiosk"},"name":"Kiosk","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Kiosko":{"tags":{"name":"Kiosko","shop":"kiosk"},"name":"Kiosko","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Kiosque":{"tags":{"name":"Kiosque","shop":"kiosk"},"name":"Kiosque","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Kolporter":{"tags":{"name":"Kolporter","shop":"kiosk"},"name":"Kolporter","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Lietuvos spauda":{"tags":{"name":"Lietuvos spauda","shop":"kiosk"},"name":"Lietuvos spauda","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Narvesen":{"tags":{"name":"Narvesen","shop":"kiosk"},"name":"Narvesen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Pressbyrån":{"tags":{"name":"Pressbyrån","shop":"kiosk"},"name":"Pressbyrån","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Pulpería":{"tags":{"name":"Pulpería","shop":"kiosk"},"name":"Pulpería","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/R-Kioski":{"tags":{"name":"R-Kioski","shop":"kiosk"},"name":"R-Kioski","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Ruch":{"tags":{"name":"Ruch","shop":"kiosk"},"name":"Ruch","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Tabak Trafik":{"tags":{"name":"Tabak Trafik","shop":"kiosk"},"name":"Tabak Trafik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Tisak":{"tags":{"name":"Tisak","shop":"kiosk"},"name":"Tisak","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Trafik":{"tags":{"name":"Trafik","shop":"kiosk"},"name":"Trafik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Trafika":{"tags":{"name":"Trafika","shop":"kiosk"},"name":"Trafika","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Trinkhalle":{"tags":{"name":"Trinkhalle","shop":"kiosk"},"name":"Trinkhalle","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Белсоюзпечать":{"tags":{"name":"Белсоюзпечать","shop":"kiosk"},"name":"Белсоюзпечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Киоск":{"tags":{"name":"Киоск","shop":"kiosk"},"name":"Киоск","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/Мороженое":{"tags":{"name":"Мороженое","shop":"kiosk"},"name":"Мороженое","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kiosk/მარკეტი (Market)":{"tags":{"name":"მარკეტი (Market)","shop":"kiosk"},"name":"მარკეტი (Market)","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kitchen/Cuisinella":{"tags":{"name":"Cuisinella","shop":"kitchen"},"name":"Cuisinella","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kitchen/Home Utensils":{"tags":{"name":"Home Utensils","shop":"kitchen"},"name":"Home Utensils","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kitchen/Kitchen":{"tags":{"name":"Kitchen","shop":"kitchen"},"name":"Kitchen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/kitchen/kitchen":{"tags":{"name":"kitchen","shop":"kitchen"},"name":"kitchen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/laundry/Launderette":{"tags":{"name":"Launderette","shop":"laundry"},"name":"Launderette","icon":"laundry","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/laundry/Lavandería":{"tags":{"name":"Lavandería","shop":"laundry"},"name":"Lavandería","icon":"laundry","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/laundry/コインランドリー":{"tags":{"name":"コインランドリー","shop":"laundry"},"name":"コインランドリー","icon":"laundry","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/lottery/Loteria de la Provincia":{"tags":{"name":"Loteria de la Provincia","shop":"lottery"},"name":"Loteria de la Provincia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/lottery/Lotería Nacional":{"tags":{"name":"Lotería Nacional","shop":"lottery"},"name":"Lotería Nacional","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/lottery/Lotería de la Provincia":{"tags":{"name":"Lotería de la Provincia","shop":"lottery"},"name":"Lotería de la Provincia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/lottery/Lotto":{"tags":{"name":"Lotto","shop":"lottery"},"name":"Lotto","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/lottery/Lottózó":{"tags":{"name":"Lottózó","shop":"lottery"},"name":"Lottózó","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/lottery/ONCE":{"tags":{"name":"ONCE","shop":"lottery"},"name":"ONCE","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mall/Торговый центр":{"tags":{"name":"Торговый центр","shop":"mall"},"name":"Торговый центр","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/massage/Massage Envy":{"tags":{"name":"Massage Envy","shop":"massage"},"name":"Massage Envy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/medical_supply/Pofam-Poznań":{"tags":{"name":"Pofam-Poznań","shop":"medical_supply"},"name":"Pofam-Poznań","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/3 Store":{"tags":{"name":"3 Store","shop":"mobile_phone"},"name":"3 Store","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/AT&T":{"tags":{"name":"AT&T","shop":"mobile_phone"},"name":"AT&T","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Bell":{"tags":{"name":"Bell","shop":"mobile_phone"},"name":"Bell","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Bitė":{"tags":{"name":"Bitė","shop":"mobile_phone"},"name":"Bitė","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Boost Mobile":{"tags":{"name":"Boost Mobile","shop":"mobile_phone"},"name":"Boost Mobile","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Carphone Warehouse":{"tags":{"name":"Carphone Warehouse","shop":"mobile_phone"},"name":"Carphone Warehouse","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Claro":{"tags":{"name":"Claro","shop":"mobile_phone"},"name":"Claro","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Cricket":{"tags":{"name":"Cricket","shop":"mobile_phone"},"name":"Cricket","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Cricket Wireless":{"tags":{"name":"Cricket Wireless","shop":"mobile_phone"},"name":"Cricket Wireless","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Digicel":{"tags":{"name":"Digicel","shop":"mobile_phone"},"name":"Digicel","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/EE":{"tags":{"name":"EE","shop":"mobile_phone"},"name":"EE","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/MetroPCS":{"tags":{"name":"MetroPCS","shop":"mobile_phone"},"name":"MetroPCS","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Movistar":{"tags":{"name":"Movistar","shop":"mobile_phone"},"name":"Movistar","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/O2":{"tags":{"name":"O2","shop":"mobile_phone"},"name":"O2","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Orange":{"tags":{"name":"Orange","shop":"mobile_phone"},"name":"Orange","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Personal":{"tags":{"name":"Personal","shop":"mobile_phone"},"name":"Personal","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Play":{"tags":{"name":"Play","shop":"mobile_phone"},"name":"Play","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Plus":{"tags":{"name":"Plus","shop":"mobile_phone"},"name":"Plus","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/SFR":{"tags":{"name":"SFR","shop":"mobile_phone"},"name":"SFR","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Sprint":{"tags":{"name":"Sprint","shop":"mobile_phone"},"name":"Sprint","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/T-Mobile":{"tags":{"name":"T-Mobile","shop":"mobile_phone"},"name":"T-Mobile","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/TIM":{"tags":{"name":"TIM","shop":"mobile_phone"},"name":"TIM","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Telcel":{"tags":{"name":"Telcel","shop":"mobile_phone"},"name":"Telcel","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Tele2":{"tags":{"name":"Tele2","shop":"mobile_phone"},"name":"Tele2","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Telekom":{"tags":{"name":"Telekom","shop":"mobile_phone"},"name":"Telekom","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Telekom Shop":{"tags":{"name":"Telekom Shop","shop":"mobile_phone"},"name":"Telekom Shop","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Telenor":{"tags":{"name":"Telenor","shop":"mobile_phone"},"name":"Telenor","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Telus":{"tags":{"name":"Telus","shop":"mobile_phone"},"name":"Telus","icon":"mobile-phone","geometry":["point","area"],"fields":["name","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":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Three":{"tags":{"name":"Three","shop":"mobile_phone"},"name":"Three","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Tim":{"tags":{"name":"Tim","shop":"mobile_phone"},"name":"Tim","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Télécentre":{"tags":{"name":"Télécentre","shop":"mobile_phone"},"name":"Télécentre","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Verizon":{"tags":{"name":"Verizon","shop":"mobile_phone"},"name":"Verizon","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Verizon Wireless":{"tags":{"name":"Verizon Wireless","shop":"mobile_phone"},"name":"Verizon Wireless","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Vodafone":{"tags":{"name":"Vodafone","shop":"mobile_phone"},"name":"Vodafone","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Vodafone Shop":{"tags":{"name":"Vodafone Shop","shop":"mobile_phone"},"name":"Vodafone Shop","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Wind":{"tags":{"name":"Wind","shop":"mobile_phone"},"name":"Wind","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Yoigo":{"tags":{"name":"Yoigo","shop":"mobile_phone"},"name":"Yoigo","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/au":{"tags":{"name":"au","shop":"mobile_phone"},"name":"au","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/auショップ":{"tags":{"name":"auショップ","shop":"mobile_phone"},"name":"auショップ","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/mobilcom debitel":{"tags":{"name":"mobilcom debitel","shop":"mobile_phone"},"name":"mobilcom debitel","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Алло":{"tags":{"name":"Алло","shop":"mobile_phone"},"name":"Алло","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Билайн":{"tags":{"name":"Билайн","shop":"mobile_phone"},"name":"Билайн","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Евросеть":{"tags":{"name":"Евросеть","shop":"mobile_phone"},"name":"Евросеть","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Київстар":{"tags":{"name":"Київстар","shop":"mobile_phone"},"name":"Київстар","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/МТС":{"tags":{"name":"МТС","shop":"mobile_phone"},"name":"МТС","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Мегафон":{"tags":{"name":"Мегафон","shop":"mobile_phone"},"name":"Мегафон","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Связной":{"tags":{"name":"Связной","shop":"mobile_phone"},"name":"Связной","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Теле2":{"tags":{"name":"Теле2","shop":"mobile_phone"},"name":"Теле2","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/ソフトバンクショップ":{"tags":{"name":"ソフトバンクショップ","shop":"mobile_phone"},"name":"ソフトバンクショップ","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/ドコモショップ":{"tags":{"name":"ドコモショップ","shop":"mobile_phone"},"name":"ドコモショップ","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/money_lender/Money Mart":{"tags":{"name":"Money Mart","shop":"money_lender"},"name":"Money Mart","icon":"bank","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","currency_multi"],"suggestion":true},"shop/motorcycle/Harley Davidson":{"tags":{"name":"Harley Davidson","shop":"motorcycle"},"name":"Harley Davidson","icon":"scooter","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/motorcycle/Yamaha":{"tags":{"name":"Yamaha","shop":"motorcycle"},"name":"Yamaha","icon":"scooter","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/music/HMV":{"tags":{"name":"HMV","shop":"music"},"name":"HMV","icon":"music","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/musical_instrument/Guitar Center":{"tags":{"name":"Guitar Center","shop":"musical_instrument"},"name":"Guitar Center","icon":"music","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Edicola":{"tags":{"name":"Edicola","shop":"newsagent"},"name":"Edicola","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Maison de la Presse":{"tags":{"name":"Maison de la Presse","shop":"newsagent"},"name":"Maison de la Presse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Relay":{"tags":{"name":"Relay","shop":"newsagent"},"name":"Relay","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Tabac Presse":{"tags":{"name":"Tabac Presse","shop":"newsagent"},"name":"Tabac Presse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/WHSmith":{"tags":{"name":"WHSmith","shop":"newsagent"},"name":"WHSmith","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Витебскоблсоюзпечать":{"tags":{"name":"Витебскоблсоюзпечать","shop":"newsagent"},"name":"Витебскоблсоюзпечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Первая полоса":{"tags":{"name":"Первая полоса","shop":"newsagent"},"name":"Первая полоса","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Печать":{"tags":{"name":"Печать","shop":"newsagent"},"name":"Печать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Роспечать":{"tags":{"name":"Роспечать","shop":"newsagent"},"name":"Роспечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/newsagent/Союзпечать":{"tags":{"name":"Союзпечать","shop":"newsagent"},"name":"Союзпечать","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Apollo":{"tags":{"name":"Apollo","shop":"optician"},"name":"Apollo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Atol":{"tags":{"name":"Atol","shop":"optician"},"name":"Atol","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Boots Opticians":{"tags":{"name":"Boots Opticians","shop":"optician"},"name":"Boots Opticians","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Fielmann":{"tags":{"name":"Fielmann","shop":"optician"},"name":"Fielmann","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/General Óptica":{"tags":{"name":"General Óptica","shop":"optician"},"name":"General Óptica","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Grand Optical":{"tags":{"name":"Grand Optical","shop":"optician"},"name":"Grand Optical","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Générale d'Optique":{"tags":{"name":"Générale d'Optique","shop":"optician"},"name":"Générale d'Optique","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Hakim Optical":{"tags":{"name":"Hakim Optical","shop":"optician"},"name":"Hakim Optical","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Hans Anders":{"tags":{"name":"Hans Anders","shop":"optician"},"name":"Hans Anders","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Krys":{"tags":{"name":"Krys","shop":"optician"},"name":"Krys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Les Opticiens Mutualistes":{"tags":{"name":"Les Opticiens Mutualistes","shop":"optician"},"name":"Les Opticiens Mutualistes","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Optica":{"tags":{"name":"Optica","shop":"optician"},"name":"Optica","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Optical Center":{"tags":{"name":"Optical Center","shop":"optician"},"name":"Optical Center","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Pearle":{"tags":{"name":"Pearle","shop":"optician"},"name":"Pearle","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Pearle Vision":{"tags":{"name":"Pearle Vision","shop":"optician"},"name":"Pearle Vision","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Specsavers":{"tags":{"name":"Specsavers","shop":"optician"},"name":"Specsavers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Sunglass Hut":{"tags":{"name":"Sunglass Hut","shop":"optician"},"name":"Sunglass Hut","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Synoptik":{"tags":{"name":"Synoptik","shop":"optician"},"name":"Synoptik","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/แว่นท็อปเจริญ":{"tags":{"name":"แว่นท็อปเจริญ","shop":"optician"},"name":"แว่นท็อปเจริญ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/メガネスーパー":{"tags":{"name":"メガネスーパー","shop":"optician"},"name":"メガネスーパー","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/眼鏡市場":{"tags":{"name":"眼鏡市場","shop":"optician"},"name":"眼鏡市場","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/outdoor/Mountain Warehouse":{"tags":{"name":"Mountain Warehouse","shop":"outdoor"},"name":"Mountain Warehouse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/outdoor/REI":{"tags":{"name":"REI","shop":"outdoor"},"name":"REI","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/outdoor/Рыболов":{"tags":{"name":"Рыболов","shop":"outdoor"},"name":"Рыболов","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/paint/Benjamin Moore":{"tags":{"name":"Benjamin Moore","shop":"paint"},"name":"Benjamin Moore","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/paint/Comex":{"tags":{"name":"Comex","shop":"paint"},"name":"Comex","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/paint/Jotun":{"tags":{"name":"Jotun","shop":"paint"},"name":"Jotun","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/paint/National Paints":{"tags":{"name":"National Paints","shop":"paint"},"name":"National Paints","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/paint/Sherwin Williams":{"tags":{"name":"Sherwin Williams","shop":"paint"},"name":"Sherwin Williams","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/paint/Sherwin-Williams Paints":{"tags":{"name":"Sherwin-Williams Paints","shop":"paint"},"name":"Sherwin-Williams Paints","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pawnbroker/Cash Converters":{"tags":{"name":"Cash Converters","shop":"pawnbroker"},"name":"Cash Converters","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pawnbroker/Lombard":{"tags":{"name":"Lombard","shop":"pawnbroker"},"name":"Lombard","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pawnbroker/Palawan Pawnshop":{"tags":{"name":"Palawan Pawnshop","shop":"pawnbroker"},"name":"Palawan Pawnshop","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Global Pet Foods":{"tags":{"name":"Global Pet Foods","shop":"pet"},"name":"Global Pet Foods","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Maxi Zoo":{"tags":{"name":"Maxi Zoo","shop":"pet"},"name":"Maxi Zoo","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Pet Valu":{"tags":{"name":"Pet Valu","shop":"pet"},"name":"Pet Valu","icon":"dog-park","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Бетховен":{"tags":{"name":"Бетховен","shop":"pet"},"name":"Бетховен","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Зоотовары":{"tags":{"name":"Зоотовары","shop":"pet"},"name":"Зоотовары","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Четыре лапы":{"tags":{"name":"Четыре лапы","shop":"pet"},"name":"Четыре лапы","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/second_hand/Goodwill":{"tags":{"name":"Goodwill","shop":"second_hand"},"name":"Goodwill","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/second_hand/Value Village":{"tags":{"name":"Value Village","shop":"second_hand"},"name":"Value Village","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/shoes/Aldo":{"tags":{"name":"Aldo","shop":"shoes"},"name":"Aldo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Bata":{"tags":{"name":"Bata","shop":"shoes"},"name":"Bata","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Besson Chaussures":{"tags":{"name":"Besson Chaussures","shop":"shoes"},"name":"Besson Chaussures","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Brantano":{"tags":{"name":"Brantano","shop":"shoes"},"name":"Brantano","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/CCC":{"tags":{"name":"CCC","shop":"shoes"},"name":"CCC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Camper":{"tags":{"name":"Camper","shop":"shoes"},"name":"Camper","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Chaussea":{"tags":{"name":"Chaussea","shop":"shoes"},"name":"Chaussea","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Clarks":{"tags":{"name":"Clarks","shop":"shoes"},"name":"Clarks","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Converse":{"tags":{"name":"Converse","shop":"shoes"},"name":"Converse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Crocs":{"tags":{"name":"Crocs","shop":"shoes"},"name":"Crocs","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/DSW":{"tags":{"name":"DSW","shop":"shoes"},"name":"DSW","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Deichmann":{"tags":{"name":"Deichmann","shop":"shoes"},"name":"Deichmann","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Dosenbach":{"tags":{"name":"Dosenbach","shop":"shoes"},"name":"Dosenbach","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Ecco":{"tags":{"name":"Ecco","shop":"shoes"},"name":"Ecco","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Geox":{"tags":{"name":"Geox","shop":"shoes"},"name":"Geox","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Kari":{"tags":{"name":"Kari","shop":"shoes"},"name":"Kari","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Mephisto":{"tags":{"name":"Mephisto","shop":"shoes"},"name":"Mephisto","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Minelli":{"tags":{"name":"Minelli","shop":"shoes"},"name":"Minelli","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/New Balance":{"tags":{"name":"New Balance","shop":"shoes"},"name":"New Balance","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Payless":{"tags":{"name":"Payless","shop":"shoes"},"name":"Payless","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Payless ShoeSource":{"tags":{"name":"Payless ShoeSource","shop":"shoes"},"name":"Payless ShoeSource","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Rack Room Shoes":{"tags":{"name":"Rack Room Shoes","shop":"shoes"},"name":"Rack Room Shoes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Reno":{"tags":{"name":"Reno","shop":"shoes"},"name":"Reno","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Rieker":{"tags":{"name":"Rieker","shop":"shoes"},"name":"Rieker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Salamander":{"tags":{"name":"Salamander","shop":"shoes"},"name":"Salamander","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/San Marina":{"tags":{"name":"San Marina","shop":"shoes"},"name":"San Marina","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Scapino":{"tags":{"name":"Scapino","shop":"shoes"},"name":"Scapino","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Shoe Carnival":{"tags":{"name":"Shoe Carnival","shop":"shoes"},"name":"Shoe Carnival","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Siemes Schuhcenter":{"tags":{"name":"Siemes Schuhcenter","shop":"shoes"},"name":"Siemes Schuhcenter","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Skechers":{"tags":{"name":"Skechers","shop":"shoes"},"name":"Skechers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Tamaris":{"tags":{"name":"Tamaris","shop":"shoes"},"name":"Tamaris","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/vanHaren":{"tags":{"name":"vanHaren","shop":"shoes"},"name":"vanHaren","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Éram":{"tags":{"name":"Éram","shop":"shoes"},"name":"Éram","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Ремонт обуви":{"tags":{"name":"Ремонт обуви","shop":"shoes"},"name":"Ремонт обуви","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/ЦентрОбувь":{"tags":{"name":"ЦентрОбувь","shop":"shoes"},"name":"ЦентрОбувь","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Юничел":{"tags":{"name":"Юничел","shop":"shoes"},"name":"Юничел","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/東京靴流通センター":{"tags":{"name":"東京靴流通センター","shop":"shoes"},"name":"東京靴流通センター","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Aktiesport":{"tags":{"name":"Aktiesport","shop":"sports"},"name":"Aktiesport","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Big 5 Sporting Goods":{"tags":{"name":"Big 5 Sporting Goods","shop":"sports"},"name":"Big 5 Sporting Goods","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Decathlon":{"tags":{"name":"Decathlon","shop":"sports"},"name":"Decathlon","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Hervis":{"tags":{"name":"Hervis","shop":"sports"},"name":"Hervis","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Intersport":{"tags":{"name":"Intersport","shop":"sports"},"name":"Intersport","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/JD Sports":{"tags":{"name":"JD Sports","shop":"sports"},"name":"JD Sports","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Stadium":{"tags":{"name":"Stadium","shop":"sports"},"name":"Stadium","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Спортмастер":{"tags":{"name":"Спортмастер","shop":"sports"},"name":"Спортмастер","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Спорттовары":{"tags":{"name":"Спорттовары","shop":"sports"},"name":"Спорттовары","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Bureau Vallée":{"tags":{"name":"Bureau Vallée","shop":"stationery"},"name":"Bureau Vallée","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Libro":{"tags":{"name":"Libro","shop":"stationery"},"name":"Libro","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/McPaper":{"tags":{"name":"McPaper","shop":"stationery"},"name":"McPaper","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Office Max":{"tags":{"name":"Office Max","shop":"stationery"},"name":"Office Max","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Officeworks":{"tags":{"name":"Officeworks","shop":"stationery"},"name":"Officeworks","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Pagro":{"tags":{"name":"Pagro","shop":"stationery"},"name":"Pagro","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Paperchase":{"tags":{"name":"Paperchase","shop":"stationery"},"name":"Paperchase","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Ryman":{"tags":{"name":"Ryman","shop":"stationery"},"name":"Ryman","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Staples":{"tags":{"name":"Staples","shop":"stationery"},"name":"Staples","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Канцтовары":{"tags":{"name":"Канцтовары","shop":"stationery"},"name":"Канцтовары","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/A&O":{"tags":{"name":"A&O","shop":"supermarket"},"name":"A&O","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/A101":{"tags":{"name":"A101","shop":"supermarket"},"name":"A101","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ADEG":{"tags":{"name":"ADEG","shop":"supermarket"},"name":"ADEG","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI":{"tags":{"name":"ALDI","shop":"supermarket"},"name":"ALDI","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Ahorramás":{"tags":{"name":"Ahorramás","shop":"supermarket"},"name":"Ahorramás","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albert":{"tags":{"name":"Albert","shop":"supermarket"},"name":"Albert","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albertsons":{"tags":{"name":"Albertsons","shop":"supermarket"},"name":"Albertsons","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Alimerka":{"tags":{"name":"Alimerka","shop":"supermarket"},"name":"Alimerka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Alnatura":{"tags":{"name":"Alnatura","shop":"supermarket"},"name":"Alnatura","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Asda":{"tags":{"name":"Asda","shop":"supermarket"},"name":"Asda","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Atac":{"tags":{"name":"Atac","shop":"supermarket"},"name":"Atac","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Atacadão":{"tags":{"name":"Atacadão","shop":"supermarket"},"name":"Atacadão","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Auchan":{"tags":{"name":"Auchan","shop":"supermarket"},"name":"Auchan","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/BM":{"tags":{"name":"BM","shop":"supermarket"},"name":"BM","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Biedronka":{"tags":{"name":"Biedronka","shop":"supermarket"},"name":"Biedronka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Big C":{"tags":{"name":"Big C","shop":"supermarket"},"name":"Big C","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Billa":{"tags":{"name":"Billa","shop":"supermarket"},"name":"Billa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Bim":{"tags":{"name":"Bim","shop":"supermarket"},"name":"Bim","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Biocoop":{"tags":{"name":"Biocoop","shop":"supermarket"},"name":"Biocoop","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Budgens":{"tags":{"name":"Budgens","shop":"supermarket"},"name":"Budgens","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Bulk Barn":{"tags":{"name":"Bulk Barn","shop":"supermarket"},"name":"Bulk Barn","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Bunnpris":{"tags":{"name":"Bunnpris","shop":"supermarket"},"name":"Bunnpris","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/CONAD":{"tags":{"name":"CONAD","shop":"supermarket"},"name":"CONAD","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/CRAI":{"tags":{"name":"CRAI","shop":"supermarket"},"name":"CRAI","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Caprabo":{"tags":{"name":"Caprabo","shop":"supermarket"},"name":"Caprabo","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Cargills Food City":{"tags":{"name":"Cargills Food City","shop":"supermarket"},"name":"Cargills Food City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour":{"tags":{"name":"Carrefour","shop":"supermarket"},"name":"Carrefour","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Casino":{"tags":{"name":"Casino","shop":"supermarket"},"name":"Casino","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Checkers":{"tags":{"name":"Checkers","shop":"supermarket"},"name":"Checkers","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Chedraui":{"tags":{"name":"Chedraui","shop":"supermarket"},"name":"Chedraui","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Co-Op":{"tags":{"name":"Co-Op","shop":"supermarket"},"name":"Co-Op","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Co-op":{"tags":{"name":"Co-op","shop":"supermarket"},"name":"Co-op","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Co-operative":{"tags":{"name":"Co-operative","shop":"supermarket"},"name":"Co-operative","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coles":{"tags":{"name":"Coles","shop":"supermarket"},"name":"Coles","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Colmado":{"tags":{"name":"Colmado","shop":"supermarket"},"name":"Colmado","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Colruyt":{"tags":{"name":"Colruyt","shop":"supermarket"},"name":"Colruyt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Combi":{"tags":{"name":"Combi","shop":"supermarket"},"name":"Combi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Comercial Mexicana":{"tags":{"name":"Comercial Mexicana","shop":"supermarket"},"name":"Comercial Mexicana","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Conad":{"tags":{"name":"Conad","shop":"supermarket"},"name":"Conad","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Conad City":{"tags":{"name":"Conad City","shop":"supermarket"},"name":"Conad City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Condis":{"tags":{"name":"Condis","shop":"supermarket"},"name":"Condis","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Consum":{"tags":{"name":"Consum","shop":"supermarket"},"name":"Consum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Continente":{"tags":{"name":"Continente","shop":"supermarket"},"name":"Continente","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop":{"tags":{"name":"Coop","shop":"supermarket"},"name":"Coop","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop Extra":{"tags":{"name":"Coop Extra","shop":"supermarket"},"name":"Coop Extra","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Costco":{"tags":{"name":"Costco","shop":"supermarket"},"name":"Costco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coto":{"tags":{"name":"Coto","shop":"supermarket"},"name":"Coto","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Countdown":{"tags":{"name":"Countdown","shop":"supermarket"},"name":"Countdown","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coviran":{"tags":{"name":"Coviran","shop":"supermarket"},"name":"Coviran","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Covirán":{"tags":{"name":"Covirán","shop":"supermarket"},"name":"Covirán","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Crai":{"tags":{"name":"Crai","shop":"supermarket"},"name":"Crai","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Cub Foods":{"tags":{"name":"Cub Foods","shop":"supermarket"},"name":"Cub Foods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dagli'Brugsen":{"tags":{"name":"Dagli'Brugsen","shop":"supermarket"},"name":"Dagli'Brugsen","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Deen":{"tags":{"name":"Deen","shop":"supermarket"},"name":"Deen","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Delhaize":{"tags":{"name":"Delhaize","shop":"supermarket"},"name":"Delhaize","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Denner":{"tags":{"name":"Denner","shop":"supermarket"},"name":"Denner","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Despar":{"tags":{"name":"Despar","shop":"supermarket"},"name":"Despar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Despensa Familiar":{"tags":{"name":"Despensa Familiar","shop":"supermarket"},"name":"Despensa Familiar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dia":{"tags":{"name":"Dia","shop":"supermarket"},"name":"Dia","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dia %":{"tags":{"name":"Dia %","shop":"supermarket"},"name":"Dia %","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dia Market":{"tags":{"name":"Dia Market","shop":"supermarket"},"name":"Dia Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dino":{"tags":{"name":"Dino","shop":"supermarket"},"name":"Dino","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dirk van den Broek":{"tags":{"name":"Dirk van den Broek","shop":"supermarket"},"name":"Dirk van den Broek","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Disco":{"tags":{"name":"Disco","shop":"supermarket"},"name":"Disco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Diska":{"tags":{"name":"Diska","shop":"supermarket"},"name":"Diska","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/E. Leclerc":{"tags":{"name":"E. Leclerc","shop":"supermarket"},"name":"E. Leclerc","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/E. Leclerc Drive":{"tags":{"name":"E. Leclerc Drive","shop":"supermarket"},"name":"E. Leclerc Drive","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/EMTÉ":{"tags":{"name":"EMTÉ","shop":"supermarket"},"name":"EMTÉ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Edeka":{"tags":{"name":"Edeka","shop":"supermarket"},"name":"Edeka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Ekom":{"tags":{"name":"Ekom","shop":"supermarket"},"name":"Ekom","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Ekono":{"tags":{"name":"Ekono","shop":"supermarket"},"name":"Ekono","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eroski":{"tags":{"name":"Eroski","shop":"supermarket"},"name":"Eroski","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Esselunga":{"tags":{"name":"Esselunga","shop":"supermarket"},"name":"Esselunga","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/EuroSpin":{"tags":{"name":"EuroSpin","shop":"supermarket"},"name":"EuroSpin","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eurospar":{"tags":{"name":"Eurospar","shop":"supermarket"},"name":"Eurospar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eurospin":{"tags":{"name":"Eurospin","shop":"supermarket"},"name":"Eurospin","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Extra":{"tags":{"name":"Extra","shop":"supermarket"},"name":"Extra","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Famila":{"tags":{"name":"Famila","shop":"supermarket"},"name":"Famila","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Fareway":{"tags":{"name":"Fareway","shop":"supermarket"},"name":"Fareway","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Farmfoods":{"tags":{"name":"Farmfoods","shop":"supermarket"},"name":"Farmfoods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Feneberg":{"tags":{"name":"Feneberg","shop":"supermarket"},"name":"Feneberg","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Foodland":{"tags":{"name":"Foodland","shop":"supermarket"},"name":"Foodland","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Foodworks":{"tags":{"name":"Foodworks","shop":"supermarket"},"name":"Foodworks","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Franprix":{"tags":{"name":"Franprix","shop":"supermarket"},"name":"Franprix","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Froiz":{"tags":{"name":"Froiz","shop":"supermarket"},"name":"Froiz","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/G20":{"tags":{"name":"G20","shop":"supermarket"},"name":"G20","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Gadis":{"tags":{"name":"Gadis","shop":"supermarket"},"name":"Gadis","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Giant":{"tags":{"name":"Giant","shop":"supermarket"},"name":"Giant","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Grand Frais":{"tags":{"name":"Grand Frais","shop":"supermarket"},"name":"Grand Frais","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Grocery Outlet":{"tags":{"name":"Grocery Outlet","shop":"supermarket"},"name":"Grocery Outlet","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/HIT":{"tags":{"name":"HIT","shop":"supermarket"},"name":"HIT","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hannaford":{"tags":{"name":"Hannaford","shop":"supermarket"},"name":"Hannaford","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Heron Foods":{"tags":{"name":"Heron Foods","shop":"supermarket"},"name":"Heron Foods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hofer":{"tags":{"name":"Hofer","shop":"supermarket"},"name":"Hofer","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hoogvliet":{"tags":{"name":"Hoogvliet","shop":"supermarket"},"name":"Hoogvliet","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ICA":{"tags":{"name":"ICA","shop":"supermarket"},"name":"ICA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ICA Kvantum":{"tags":{"name":"ICA Kvantum","shop":"supermarket"},"name":"ICA Kvantum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/IDEA":{"tags":{"name":"IDEA","shop":"supermarket"},"name":"IDEA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/IGA":{"tags":{"name":"IGA","shop":"supermarket"},"name":"IGA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Iceland":{"tags":{"name":"Iceland","shop":"supermarket"},"name":"Iceland","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarché":{"tags":{"name":"Intermarché","shop":"supermarket"},"name":"Intermarché","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarché Contact":{"tags":{"name":"Intermarché Contact","shop":"supermarket"},"name":"Intermarché Contact","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarché Super":{"tags":{"name":"Intermarché Super","shop":"supermarket"},"name":"Intermarché Super","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Interspar":{"tags":{"name":"Interspar","shop":"supermarket"},"name":"Interspar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Irma":{"tags":{"name":"Irma","shop":"supermarket"},"name":"Irma","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Jewel-Osco":{"tags":{"name":"Jewel-Osco","shop":"supermarket"},"name":"Jewel-Osco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Jumbo":{"tags":{"name":"Jumbo","shop":"supermarket"},"name":"Jumbo","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaufland":{"tags":{"name":"Kaufland","shop":"supermarket"},"name":"Kaufland","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kiwi":{"tags":{"name":"Kiwi","shop":"supermarket"},"name":"Kiwi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Konsum":{"tags":{"name":"Konsum","shop":"supermarket"},"name":"Konsum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Konzum":{"tags":{"name":"Konzum","shop":"supermarket"},"name":"Konzum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kroger":{"tags":{"name":"Kroger","shop":"supermarket"},"name":"Kroger","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kvickly":{"tags":{"name":"Kvickly","shop":"supermarket"},"name":"Kvickly","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/La Vie Claire":{"tags":{"name":"La Vie Claire","shop":"supermarket"},"name":"La Vie Claire","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Landi":{"tags":{"name":"Landi","shop":"supermarket"},"name":"Landi","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lider":{"tags":{"name":"Lider","shop":"supermarket"},"name":"Lider","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lidl":{"tags":{"name":"Lidl","shop":"supermarket"},"name":"Lidl","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lupa":{"tags":{"name":"Lupa","shop":"supermarket"},"name":"Lupa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/MPREIS":{"tags":{"name":"MPREIS","shop":"supermarket"},"name":"MPREIS","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Makro":{"tags":{"name":"Makro","shop":"supermarket"},"name":"Makro","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Markant":{"tags":{"name":"Markant","shop":"supermarket"},"name":"Markant","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Market Basket":{"tags":{"name":"Market Basket","shop":"supermarket"},"name":"Market Basket","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Marktkauf":{"tags":{"name":"Marktkauf","shop":"supermarket"},"name":"Marktkauf","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Match":{"tags":{"name":"Match","shop":"supermarket"},"name":"Match","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxi":{"tags":{"name":"Maxi","shop":"supermarket"},"name":"Maxi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxi Dia":{"tags":{"name":"Maxi Dia","shop":"supermarket"},"name":"Maxi Dia","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxima":{"tags":{"name":"Maxima","shop":"supermarket"},"name":"Maxima","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxima XX":{"tags":{"name":"Maxima XX","shop":"supermarket"},"name":"Maxima XX","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mega Image":{"tags":{"name":"Mega Image","shop":"supermarket"},"name":"Mega Image","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mego":{"tags":{"name":"Mego","shop":"supermarket"},"name":"Mego","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Meijer":{"tags":{"name":"Meijer","shop":"supermarket"},"name":"Meijer","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Meny":{"tags":{"name":"Meny","shop":"supermarket"},"name":"Meny","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercado":{"tags":{"name":"Mercado","shop":"supermarket"},"name":"Mercado","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercado Municipal":{"tags":{"name":"Mercado Municipal","shop":"supermarket"},"name":"Mercado Municipal","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercado de Abastos":{"tags":{"name":"Mercado de Abastos","shop":"supermarket"},"name":"Mercado de Abastos","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercadona":{"tags":{"name":"Mercadona","shop":"supermarket"},"name":"Mercadona","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercator":{"tags":{"name":"Mercator","shop":"supermarket"},"name":"Mercator","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Merkur":{"tags":{"name":"Merkur","shop":"supermarket"},"name":"Merkur","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Metro":{"tags":{"name":"Metro","shop":"supermarket"},"name":"Metro","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Migros":{"tags":{"name":"Migros","shop":"supermarket"},"name":"Migros","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mila":{"tags":{"name":"Mila","shop":"supermarket"},"name":"Mila","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mix Markt":{"tags":{"name":"Mix Markt","shop":"supermarket"},"name":"Mix Markt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Monoprix":{"tags":{"name":"Monoprix","shop":"supermarket"},"name":"Monoprix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/More":{"tags":{"name":"More","shop":"supermarket"},"name":"More","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Morrisons":{"tags":{"name":"Morrisons","shop":"supermarket"},"name":"Morrisons","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NETTO":{"tags":{"name":"NETTO","shop":"supermarket"},"name":"NETTO","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NORMA":{"tags":{"name":"NORMA","shop":"supermarket"},"name":"NORMA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NP":{"tags":{"name":"NP","shop":"supermarket"},"name":"NP","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Nahkauf":{"tags":{"name":"Nahkauf","shop":"supermarket"},"name":"Nahkauf","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Netto Marken-Discount":{"tags":{"name":"Netto Marken-Discount","shop":"supermarket"},"name":"Netto Marken-Discount","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Norma":{"tags":{"name":"Norma","shop":"supermarket"},"name":"Norma","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/PENNY":{"tags":{"name":"PENNY","shop":"supermarket"},"name":"PENNY","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/PLUS":{"tags":{"name":"PLUS","shop":"supermarket"},"name":"PLUS","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/POLOmarket":{"tags":{"name":"POLOmarket","shop":"supermarket"},"name":"POLOmarket","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Palí":{"tags":{"name":"Palí","shop":"supermarket"},"name":"Palí","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pam":{"tags":{"name":"Pam","shop":"supermarket"},"name":"Pam","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny":{"tags":{"name":"Penny","shop":"supermarket"},"name":"Penny","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Plaza Vea":{"tags":{"name":"Plaza Vea","shop":"supermarket"},"name":"Plaza Vea","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Plodine":{"tags":{"name":"Plodine","shop":"supermarket"},"name":"Plodine","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Poiesz":{"tags":{"name":"Poiesz","shop":"supermarket"},"name":"Poiesz","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Prix":{"tags":{"name":"Prix","shop":"supermarket"},"name":"Prix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Profi":{"tags":{"name":"Profi","shop":"supermarket"},"name":"Profi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Proxy Delhaize":{"tags":{"name":"Proxy Delhaize","shop":"supermarket"},"name":"Proxy Delhaize","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Publix":{"tags":{"name":"Publix","shop":"supermarket"},"name":"Publix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Punto Simply":{"tags":{"name":"Punto Simply","shop":"supermarket"},"name":"Punto Simply","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Puregold":{"tags":{"name":"Puregold","shop":"supermarket"},"name":"Puregold","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pão de Açúcar":{"tags":{"name":"Pão de Açúcar","shop":"supermarket"},"name":"Pão de Açúcar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/QFC":{"tags":{"name":"QFC","shop":"supermarket"},"name":"QFC","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/REWE City":{"tags":{"name":"REWE City","shop":"supermarket"},"name":"REWE City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Ralphs":{"tags":{"name":"Ralphs","shop":"supermarket"},"name":"Ralphs","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Real":{"tags":{"name":"Real","shop":"supermarket"},"name":"Real","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Real Canadian Superstore":{"tags":{"name":"Real Canadian Superstore","shop":"supermarket"},"name":"Real Canadian Superstore","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rewe":{"tags":{"name":"Rewe","shop":"supermarket"},"name":"Rewe","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rimi":{"tags":{"name":"Rimi","shop":"supermarket"},"name":"Rimi","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Safeway":{"tags":{"name":"Safeway","shop":"supermarket"},"name":"Safeway","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Save-A-Lot":{"tags":{"name":"Save-A-Lot","shop":"supermarket"},"name":"Save-A-Lot","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ShopRite":{"tags":{"name":"ShopRite","shop":"supermarket"},"name":"ShopRite","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Shoprite":{"tags":{"name":"Shoprite","shop":"supermarket"},"name":"Shoprite","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sigma":{"tags":{"name":"Sigma","shop":"supermarket"},"name":"Sigma","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sky":{"tags":{"name":"Sky","shop":"supermarket"},"name":"Sky","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Smith's":{"tags":{"name":"Smith's","shop":"supermarket"},"name":"Smith's","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sobeys":{"tags":{"name":"Sobeys","shop":"supermarket"},"name":"Sobeys","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Soriana":{"tags":{"name":"Soriana","shop":"supermarket"},"name":"Soriana","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Spar":{"tags":{"name":"Spar","shop":"supermarket"},"name":"Spar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sprouts Farmers Market":{"tags":{"name":"Sprouts Farmers Market","shop":"supermarket"},"name":"Sprouts Farmers Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Stokrotka":{"tags":{"name":"Stokrotka","shop":"supermarket"},"name":"Stokrotka","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Super C":{"tags":{"name":"Super C","shop":"supermarket"},"name":"Super C","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/SuperBrugsen":{"tags":{"name":"SuperBrugsen","shop":"supermarket"},"name":"SuperBrugsen","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/SuperValu":{"tags":{"name":"SuperValu","shop":"supermarket"},"name":"SuperValu","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Superama":{"tags":{"name":"Superama","shop":"supermarket"},"name":"Superama","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Supersol":{"tags":{"name":"Supersol","shop":"supermarket"},"name":"Supersol","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Superspar":{"tags":{"name":"Superspar","shop":"supermarket"},"name":"Superspar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tegut":{"tags":{"name":"Tegut","shop":"supermarket"},"name":"Tegut","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tengelmann":{"tags":{"name":"Tengelmann","shop":"supermarket"},"name":"Tengelmann","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco":{"tags":{"name":"Tesco","shop":"supermarket"},"name":"Tesco","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tommy":{"tags":{"name":"Tommy","shop":"supermarket"},"name":"Tommy","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tottus":{"tags":{"name":"Tottus","shop":"supermarket"},"name":"Tottus","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Unimarc":{"tags":{"name":"Unimarc","shop":"supermarket"},"name":"Unimarc","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Unimarkt":{"tags":{"name":"Unimarkt","shop":"supermarket"},"name":"Unimarkt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Utile":{"tags":{"name":"Utile","shop":"supermarket"},"name":"Utile","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Vea":{"tags":{"name":"Vea","shop":"supermarket"},"name":"Vea","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Volg":{"tags":{"name":"Volg","shop":"supermarket"},"name":"Volg","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Waitrose":{"tags":{"name":"Waitrose","shop":"supermarket"},"name":"Waitrose","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Walmart":{"tags":{"name":"Walmart","shop":"supermarket"},"name":"Walmart","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Walmart Neighborhood Market":{"tags":{"name":"Walmart Neighborhood Market","shop":"supermarket"},"name":"Walmart Neighborhood Market","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wasgau":{"tags":{"name":"Wasgau","shop":"supermarket"},"name":"Wasgau","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wegmans":{"tags":{"name":"Wegmans","shop":"supermarket"},"name":"Wegmans","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wellcome":{"tags":{"name":"Wellcome","shop":"supermarket"},"name":"Wellcome","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Whole Foods Market":{"tags":{"name":"Whole Foods Market","shop":"supermarket"},"name":"Whole Foods Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Willys":{"tags":{"name":"Willys","shop":"supermarket"},"name":"Willys","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/WinCo Foods":{"tags":{"name":"WinCo Foods","shop":"supermarket"},"name":"WinCo Foods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Winn Dixie":{"tags":{"name":"Winn Dixie","shop":"supermarket"},"name":"Winn Dixie","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Woolworths":{"tags":{"name":"Woolworths","shop":"supermarket"},"name":"Woolworths","icon":"grocery","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/fakta":{"tags":{"name":"fakta","shop":"supermarket"},"name":"fakta","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/real":{"tags":{"name":"real","shop":"supermarket"},"name":"real","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/tegut":{"tags":{"name":"tegut","shop":"supermarket"},"name":"tegut","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Şok":{"tags":{"name":"Şok","shop":"supermarket"},"name":"Şok","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ΑΒ Βασιλόπουλος":{"tags":{"name":"ΑΒ Βασιλόπουλος","shop":"supermarket"},"name":"ΑΒ Βασιλόπουλος","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Γαλαξίας":{"tags":{"name":"Γαλαξίας","shop":"supermarket"},"name":"Γαλαξίας","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Μασούτης":{"tags":{"name":"Μασούτης","shop":"supermarket"},"name":"Μασούτης","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Σκλαβενίτης":{"tags":{"name":"Σκλαβενίτης","shop":"supermarket"},"name":"Σκλαβενίτης","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/АТБ":{"tags":{"name":"АТБ","shop":"supermarket"},"name":"АТБ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Абсолют":{"tags":{"name":"Абсолют","shop":"supermarket"},"name":"Абсолют","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Азбука Вкуса":{"tags":{"name":"Азбука Вкуса","shop":"supermarket"},"name":"Азбука Вкуса","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Атак":{"tags":{"name":"Атак","shop":"supermarket"},"name":"Атак","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Ашан":{"tags":{"name":"Ашан","shop":"supermarket"},"name":"Ашан","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Верный":{"tags":{"name":"Верный","shop":"supermarket"},"name":"Верный","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Вопак":{"tags":{"name":"Вопак","shop":"supermarket"},"name":"Вопак","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Гроздь":{"tags":{"name":"Гроздь","shop":"supermarket"},"name":"Гроздь","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Десяточка":{"tags":{"name":"Десяточка","shop":"supermarket"},"name":"Десяточка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Дикси":{"tags":{"name":"Дикси","shop":"supermarket"},"name":"Дикси","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Евроопт":{"tags":{"name":"Евроопт","shop":"supermarket"},"name":"Евроопт","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Карусель":{"tags":{"name":"Карусель","shop":"supermarket"},"name":"Карусель","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Квартал":{"tags":{"name":"Квартал","shop":"supermarket"},"name":"Квартал","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Командор":{"tags":{"name":"Командор","shop":"supermarket"},"name":"Командор","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Красный Яр":{"tags":{"name":"Красный Яр","shop":"supermarket"},"name":"Красный Яр","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Лента":{"tags":{"name":"Лента","shop":"supermarket"},"name":"Лента","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Магнит":{"tags":{"name":"Магнит","shop":"supermarket"},"name":"Магнит","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Магнолия":{"tags":{"name":"Магнолия","shop":"supermarket"},"name":"Магнолия","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Монетка":{"tags":{"name":"Монетка","shop":"supermarket"},"name":"Монетка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Народная 7Я семьЯ":{"tags":{"name":"Народная 7Я семьЯ","shop":"supermarket"},"name":"Народная 7Я семьЯ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Перекресток":{"tags":{"name":"Перекресток","shop":"supermarket"},"name":"Перекресток","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Покупочка":{"tags":{"name":"Покупочка","shop":"supermarket"},"name":"Покупочка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Полушка":{"tags":{"name":"Полушка","shop":"supermarket"},"name":"Полушка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Пятёрочка":{"tags":{"name":"Пятёрочка","shop":"supermarket"},"name":"Пятёрочка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Радеж":{"tags":{"name":"Радеж","shop":"supermarket"},"name":"Радеж","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Рукавичка":{"tags":{"name":"Рукавичка","shop":"supermarket"},"name":"Рукавичка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Светофор":{"tags":{"name":"Светофор","shop":"supermarket"},"name":"Светофор","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Седьмой континент":{"tags":{"name":"Седьмой континент","shop":"supermarket"},"name":"Седьмой континент","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Семейный":{"tags":{"name":"Семейный","shop":"supermarket"},"name":"Семейный","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Семья":{"tags":{"name":"Семья","shop":"supermarket"},"name":"Семья","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Супермаркет":{"tags":{"name":"Супермаркет","shop":"supermarket"},"name":"Супермаркет","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Сільпо":{"tags":{"name":"Сільпо","shop":"supermarket"},"name":"Сільпо","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Таврія‑В":{"tags":{"name":"Таврія‑В","shop":"supermarket"},"name":"Таврія‑В","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Фора":{"tags":{"name":"Фора","shop":"supermarket"},"name":"Фора","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Фуршет":{"tags":{"name":"Фуршет","shop":"supermarket"},"name":"Фуршет","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Хүнсний дэлгүүр":{"tags":{"name":"Хүнсний дэлгүүр","shop":"supermarket"},"name":"Хүнсний дэлгүүр","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Эдельвейс":{"tags":{"name":"Эдельвейс","shop":"supermarket"},"name":"Эдельвейс","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/хүнсний дэлгүүр":{"tags":{"name":"хүнсний дэлгүүр","shop":"supermarket"},"name":"хүнсний дэлгүүр","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/بقالة":{"tags":{"name":"بقالة","shop":"supermarket"},"name":"بقالة","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/سوپر مارکت":{"tags":{"name":"سوپر مارکت","shop":"supermarket"},"name":"سوپر مارکت","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/سوپرمارکت":{"tags":{"name":"سوپرمارکت","shop":"supermarket"},"name":"سوپرمارکت","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/いなげや":{"tags":{"name":"いなげや","shop":"supermarket"},"name":"いなげや","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/まいばすけっと":{"tags":{"name":"まいばすけっと","shop":"supermarket"},"name":"まいばすけっと","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/イオン":{"tags":{"name":"イオン","shop":"supermarket"},"name":"イオン","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/イトーヨーカドー":{"tags":{"name":"イトーヨーカドー","shop":"supermarket"},"name":"イトーヨーカドー","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/カスミ":{"tags":{"name":"カスミ","shop":"supermarket"},"name":"カスミ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/マックスバリュ":{"tags":{"name":"マックスバリュ","shop":"supermarket"},"name":"マックスバリュ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/マルエツ":{"tags":{"name":"マルエツ","shop":"supermarket"},"name":"マルエツ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ライフ":{"tags":{"name":"ライフ","shop":"supermarket"},"name":"ライフ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/全聯":{"tags":{"name":"全聯","shop":"supermarket"},"name":"全聯","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/全聯福利中心":{"tags":{"name":"全聯福利中心","shop":"supermarket"},"name":"全聯福利中心","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/惠康 Wellcome":{"tags":{"name":"惠康 Wellcome","shop":"supermarket"},"name":"惠康 Wellcome","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/業務スーパー":{"tags":{"name":"業務スーパー","shop":"supermarket"},"name":"業務スーパー","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/美廉社":{"tags":{"name":"美廉社","shop":"supermarket"},"name":"美廉社","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/西友":{"tags":{"name":"西友","shop":"supermarket"},"name":"西友","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tailor/Atelier de couture":{"tags":{"name":"Atelier de couture","shop":"tailor"},"name":"Atelier de couture","icon":"clothing-store","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tattoo/Tattoo":{"tags":{"name":"Tattoo","shop":"tattoo"},"name":"Tattoo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/ticket/Boutique Grandes Lignes":{"tags":{"name":"Boutique Grandes Lignes","shop":"ticket"},"name":"Boutique Grandes Lignes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/ticket/Guichet Transilien":{"tags":{"name":"Guichet Transilien","shop":"ticket"},"name":"Guichet Transilien","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/ticket/Касса":{"tags":{"name":"Касса","shop":"ticket"},"name":"Касса","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/ticket/Проездные билеты":{"tags":{"name":"Проездные билеты","shop":"ticket"},"name":"Проездные билеты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tobacco/Dohánybolt":{"tags":{"name":"Dohánybolt","shop":"tobacco"},"name":"Dohánybolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tobacco/Estanco":{"tags":{"name":"Estanco","shop":"tobacco"},"name":"Estanco","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tobacco/Nemzeti Dohánybolt":{"tags":{"name":"Nemzeti Dohánybolt","shop":"tobacco"},"name":"Nemzeti Dohánybolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tobacco/Tabacos":{"tags":{"name":"Tabacos","shop":"tobacco"},"name":"Tabacos","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tobacco/Табакерка":{"tags":{"name":"Табакерка","shop":"tobacco"},"name":"Табакерка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Dráčik":{"tags":{"name":"Dráčik","shop":"toys"},"name":"Dráčik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Intertoys":{"tags":{"name":"Intertoys","shop":"toys"},"name":"Intertoys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/King Jouet":{"tags":{"name":"King Jouet","shop":"toys"},"name":"King Jouet","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Maxi Toys":{"tags":{"name":"Maxi Toys","shop":"toys"},"name":"Maxi Toys","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Детский мир":{"tags":{"name":"Детский мир","shop":"toys"},"name":"Детский мир","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Игрушки":{"tags":{"name":"Игрушки","shop":"toys"},"name":"Игрушки","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/D-reizen":{"tags":{"name":"D-reizen","shop":"travel_agency"},"name":"D-reizen","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/DER Reisebüro":{"tags":{"name":"DER Reisebüro","shop":"travel_agency"},"name":"DER Reisebüro","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/First Reisebüro":{"tags":{"name":"First Reisebüro","shop":"travel_agency"},"name":"First Reisebüro","icon":"suitcase","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/Reiseland":{"tags":{"name":"Reiseland","shop":"travel_agency"},"name":"Reiseland","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/TUI":{"tags":{"name":"TUI","shop":"travel_agency"},"name":"TUI","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/The Co-operative Travel":{"tags":{"name":"The Co-operative Travel","shop":"travel_agency"},"name":"The Co-operative Travel","icon":"suitcase","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/Thomson":{"tags":{"name":"Thomson","shop":"travel_agency"},"name":"Thomson","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Borracharia":{"tags":{"name":"Borracharia","shop":"tyres"},"name":"Borracharia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Bridgestone":{"tags":{"name":"Bridgestone","shop":"tyres"},"name":"Bridgestone","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Discount Tire":{"tags":{"name":"Discount Tire","shop":"tyres"},"name":"Discount Tire","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Les Schwab Tire Center":{"tags":{"name":"Les Schwab Tire Center","shop":"tyres"},"name":"Les Schwab Tire Center","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Vianor":{"tags":{"name":"Vianor","shop":"tyres"},"name":"Vianor","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Vulcanizing Shop":{"tags":{"name":"Vulcanizing Shop","shop":"tyres"},"name":"Vulcanizing Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/tyres/Вулканизация":{"tags":{"name":"Вулканизация","shop":"tyres"},"name":"Вулканизация","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Action":{"tags":{"name":"Action","shop":"variety_store"},"name":"Action","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Bazar":{"tags":{"name":"Bazar","shop":"variety_store"},"name":"Bazar","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Big Bazar":{"tags":{"name":"Big Bazar","shop":"variety_store"},"name":"Big Bazar","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/EuroShop":{"tags":{"name":"EuroShop","shop":"variety_store"},"name":"EuroShop","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Fix Price":{"tags":{"name":"Fix Price","shop":"variety_store"},"name":"Fix Price","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Fix price":{"tags":{"name":"Fix price","shop":"variety_store"},"name":"Fix price","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/FixPrice":{"tags":{"name":"FixPrice","shop":"variety_store"},"name":"FixPrice","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/GiFi":{"tags":{"name":"GiFi","shop":"variety_store"},"name":"GiFi","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Home Bargains":{"tags":{"name":"Home Bargains","shop":"variety_store"},"name":"Home Bargains","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Mäc-Geiz":{"tags":{"name":"Mäc-Geiz","shop":"variety_store"},"name":"Mäc-Geiz","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/NOZ":{"tags":{"name":"NOZ","shop":"variety_store"},"name":"NOZ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Poundland":{"tags":{"name":"Poundland","shop":"variety_store"},"name":"Poundland","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Poundworld":{"tags":{"name":"Poundworld","shop":"variety_store"},"name":"Poundworld","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/ダイソー":{"tags":{"name":"ダイソー","shop":"variety_store"},"name":"ダイソー","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/Blockbuster":{"tags":{"name":"Blockbuster","shop":"video"},"name":"Blockbuster","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/Family Video":{"tags":{"name":"Family Video","shop":"video"},"name":"Family Video","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/TSUTAYA":{"tags":{"name":"TSUTAYA","shop":"video"},"name":"TSUTAYA","icon":"shop","geometry":["point","area"],"fields":["name","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":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/ゲオ":{"tags":{"name":"ゲオ","shop":"video"},"name":"ゲオ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video_games/EB Games":{"tags":{"name":"EB Games","shop":"video_games"},"name":"EB Games","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video_games/Game":{"tags":{"name":"Game","shop":"video_games"},"name":"Game","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video_games/GameStop":{"tags":{"name":"GameStop","shop":"video_games"},"name":"GameStop","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/video_games/Micromania":{"tags":{"name":"Micromania","shop":"video_games"},"name":"Micromania","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/alpine_hut/КОШ":{"tags":{"name":"КОШ","tourism":"alpine_hut"},"name":"КОШ","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/apartment/Двухкомнатная квартира на сутки":{"tags":{"name":"Двухкомнатная квартира на сутки","tourism":"apartment"},"name":"Двухкомнатная квартира на сутки","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/attraction/Arch":{"tags":{"name":"Arch","tourism":"attraction"},"name":"Arch","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Kursächsische Postmeilensäule":{"tags":{"name":"Kursächsische Postmeilensäule","tourism":"attraction"},"name":"Kursächsische Postmeilensäule","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Lavoir":{"tags":{"name":"Lavoir","tourism":"attraction"},"name":"Lavoir","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Maibaum":{"tags":{"name":"Maibaum","tourism":"attraction"},"name":"Maibaum","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Moab trail":{"tags":{"name":"Moab trail","tourism":"attraction"},"name":"Moab trail","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Moai":{"tags":{"name":"Moai","tourism":"attraction"},"name":"Moai","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/OWŚ":{"tags":{"name":"OWŚ","tourism":"attraction"},"name":"OWŚ","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Sommerrodelbahn":{"tags":{"name":"Sommerrodelbahn","tourism":"attraction"},"name":"Sommerrodelbahn","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/path continues":{"tags":{"name":"path continues","tourism":"attraction"},"name":"path continues","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/path contiunes":{"tags":{"name":"path contiunes","tourism":"attraction"},"name":"path contiunes","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/white blaze":{"tags":{"name":"white blaze","tourism":"attraction"},"name":"white blaze","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Кладбище еврейское":{"tags":{"name":"Кладбище еврейское","tourism":"attraction"},"name":"Кладбище еврейское","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Колесо обозрения":{"tags":{"name":"Колесо обозрения","tourism":"attraction"},"name":"Колесо обозрения","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Приусадебный парк":{"tags":{"name":"Приусадебный парк","tourism":"attraction"},"name":"Приусадебный парк","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Усадьба":{"tags":{"name":"Усадьба","tourism":"attraction"},"name":"Усадьба","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Хозяйственный двор":{"tags":{"name":"Хозяйственный двор","tourism":"attraction"},"name":"Хозяйственный двор","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Часовня":{"tags":{"name":"Часовня","tourism":"attraction"},"name":"Часовня","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/дольмен":{"tags":{"name":"дольмен","tourism":"attraction"},"name":"дольмен","icon":"monument","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/camp_site/Camping Municipal":{"tags":{"name":"Camping Municipal","tourism":"camp_site"},"name":"Camping Municipal","icon":"campsite","geometry":["point","vertex","area"],"fields":["name","operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/camp_site/Camping municipal":{"tags":{"name":"Camping municipal","tourism":"camp_site"},"name":"Camping municipal","icon":"campsite","geometry":["point","vertex","area"],"fields":["name","operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/camp_site/Campsite":{"tags":{"name":"Campsite","tourism":"camp_site"},"name":"Campsite","icon":"campsite","geometry":["point","vertex","area"],"fields":["name","operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/guest_house/Guest House":{"tags":{"name":"Guest House","tourism":"guest_house"},"name":"Guest House","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/guest_house/Home":{"tags":{"name":"Home","tourism":"guest_house"},"name":"Home","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/guest_house/OW Bielanka":{"tags":{"name":"OW Bielanka","tourism":"guest_house"},"name":"OW Bielanka","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hostel/Albergue de Peregrinos":{"tags":{"name":"Albergue de Peregrinos","tourism":"hostel"},"name":"Albergue de Peregrinos","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hostel/Hospedaje":{"tags":{"name":"Hospedaje","tourism":"hostel"},"name":"Hospedaje","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hostel/Hostal":{"tags":{"name":"Hostal","tourism":"hostel"},"name":"Hostal","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/B&B Hôtel":{"tags":{"name":"B&B Hôtel","tourism":"hotel"},"name":"B&B Hôtel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/B&b Hôtel":{"tags":{"name":"B&b Hôtel","tourism":"hotel"},"name":"B&b Hôtel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Best Western":{"tags":{"name":"Best Western","tourism":"hotel"},"name":"Best Western","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Campanile":{"tags":{"name":"Campanile","tourism":"hotel"},"name":"Campanile","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Central Hotel":{"tags":{"name":"Central Hotel","tourism":"hotel"},"name":"Central Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/City Hotel":{"tags":{"name":"City Hotel","tourism":"hotel"},"name":"City Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Comfort Inn":{"tags":{"name":"Comfort Inn","tourism":"hotel"},"name":"Comfort Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Comfort Inn & Suites":{"tags":{"name":"Comfort Inn & Suites","tourism":"hotel"},"name":"Comfort Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Comfort Suites":{"tags":{"name":"Comfort Suites","tourism":"hotel"},"name":"Comfort Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Country Inn & Suites":{"tags":{"name":"Country Inn & Suites","tourism":"hotel"},"name":"Country Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Courtyard by Marriott":{"tags":{"name":"Courtyard by Marriott","tourism":"hotel"},"name":"Courtyard by Marriott","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Crowne Plaza":{"tags":{"name":"Crowne Plaza","tourism":"hotel"},"name":"Crowne Plaza","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Days Inn":{"tags":{"name":"Days Inn","tourism":"hotel"},"name":"Days Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Embassy Suites":{"tags":{"name":"Embassy Suites","tourism":"hotel"},"name":"Embassy Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Extended Stay America":{"tags":{"name":"Extended Stay America","tourism":"hotel"},"name":"Extended Stay America","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Fairfield Inn":{"tags":{"name":"Fairfield Inn","tourism":"hotel"},"name":"Fairfield Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Fairfield Inn & Suites":{"tags":{"name":"Fairfield Inn & Suites","tourism":"hotel"},"name":"Fairfield Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Formule 1":{"tags":{"name":"Formule 1","tourism":"hotel"},"name":"Formule 1","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Grand Hotel":{"tags":{"name":"Grand Hotel","tourism":"hotel"},"name":"Grand Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hampton Inn":{"tags":{"name":"Hampton Inn","tourism":"hotel"},"name":"Hampton Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hampton Inn & Suites":{"tags":{"name":"Hampton Inn & Suites","tourism":"hotel"},"name":"Hampton Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hilton Garden Inn":{"tags":{"name":"Hilton Garden Inn","tourism":"hotel"},"name":"Hilton Garden Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Holiday Inn":{"tags":{"name":"Holiday Inn","tourism":"hotel"},"name":"Holiday Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Holiday Inn Express":{"tags":{"name":"Holiday Inn Express","tourism":"hotel"},"name":"Holiday Inn Express","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Holiday Inn Express & Suites":{"tags":{"name":"Holiday Inn Express & Suites","tourism":"hotel"},"name":"Holiday Inn Express & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Homewood Suites":{"tags":{"name":"Homewood Suites","tourism":"hotel"},"name":"Homewood Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Central":{"tags":{"name":"Hotel Central","tourism":"hotel"},"name":"Hotel Central","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Europa":{"tags":{"name":"Hotel Europa","tourism":"hotel"},"name":"Hotel Europa","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Ibis":{"tags":{"name":"Hotel Ibis","tourism":"hotel"},"name":"Hotel Ibis","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Krone":{"tags":{"name":"Hotel Krone","tourism":"hotel"},"name":"Hotel Krone","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Panorama":{"tags":{"name":"Hotel Panorama","tourism":"hotel"},"name":"Hotel Panorama","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Plaza":{"tags":{"name":"Hotel Plaza","tourism":"hotel"},"name":"Hotel Plaza","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Post":{"tags":{"name":"Hotel Post","tourism":"hotel"},"name":"Hotel Post","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Royal":{"tags":{"name":"Hotel Royal","tourism":"hotel"},"name":"Hotel Royal","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Victoria":{"tags":{"name":"Hotel Victoria","tourism":"hotel"},"name":"Hotel Victoria","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel zur Post":{"tags":{"name":"Hotel zur Post","tourism":"hotel"},"name":"Hotel zur Post","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hôtel Ibis":{"tags":{"name":"Hôtel Ibis","tourism":"hotel"},"name":"Hôtel Ibis","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hôtel de France":{"tags":{"name":"Hôtel de France","tourism":"hotel"},"name":"Hôtel de France","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ibis":{"tags":{"name":"Ibis","tourism":"hotel"},"name":"Ibis","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ibis Budget":{"tags":{"name":"Ibis Budget","tourism":"hotel"},"name":"Ibis Budget","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ibis Styles":{"tags":{"name":"Ibis Styles","tourism":"hotel"},"name":"Ibis Styles","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Kyriad":{"tags":{"name":"Kyriad","tourism":"hotel"},"name":"Kyriad","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/La Quinta":{"tags":{"name":"La Quinta","tourism":"hotel"},"name":"La Quinta","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Marriott":{"tags":{"name":"Marriott","tourism":"hotel"},"name":"Marriott","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Mercure":{"tags":{"name":"Mercure","tourism":"hotel"},"name":"Mercure","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Novotel":{"tags":{"name":"Novotel","tourism":"hotel"},"name":"Novotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Palace Hotel":{"tags":{"name":"Palace Hotel","tourism":"hotel"},"name":"Palace Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Park Hotel":{"tags":{"name":"Park Hotel","tourism":"hotel"},"name":"Park Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Parkhotel":{"tags":{"name":"Parkhotel","tourism":"hotel"},"name":"Parkhotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Premier Inn":{"tags":{"name":"Premier Inn","tourism":"hotel"},"name":"Premier Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Première Classe":{"tags":{"name":"Première Classe","tourism":"hotel"},"name":"Première Classe","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Quality Inn":{"tags":{"name":"Quality Inn","tourism":"hotel"},"name":"Quality Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Quality Inn & Suites":{"tags":{"name":"Quality Inn & Suites","tourism":"hotel"},"name":"Quality Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ramada":{"tags":{"name":"Ramada","tourism":"hotel"},"name":"Ramada","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Residence Inn":{"tags":{"name":"Residence Inn","tourism":"hotel"},"name":"Residence Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Royal Hotel":{"tags":{"name":"Royal Hotel","tourism":"hotel"},"name":"Royal Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Sheraton":{"tags":{"name":"Sheraton","tourism":"hotel"},"name":"Sheraton","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Sleep Inn":{"tags":{"name":"Sleep Inn","tourism":"hotel"},"name":"Sleep Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Staybridge Suites":{"tags":{"name":"Staybridge Suites","tourism":"hotel"},"name":"Staybridge Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Super 8":{"tags":{"name":"Super 8","tourism":"hotel"},"name":"Super 8","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Travelodge":{"tags":{"name":"Travelodge","tourism":"hotel"},"name":"Travelodge","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Гостиница":{"tags":{"name":"Гостиница","tourism":"hotel"},"name":"Гостиница","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/東横イン":{"tags":{"name":"東横イン","tourism":"hotel"},"name":"東横イン","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Budget Inn":{"tags":{"name":"Budget Inn","tourism":"motel"},"name":"Budget Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Econo Lodge":{"tags":{"name":"Econo Lodge","tourism":"motel"},"name":"Econo Lodge","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Motel":{"tags":{"name":"Motel","tourism":"motel"},"name":"Motel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Motel 6":{"tags":{"name":"Motel 6","tourism":"motel"},"name":"Motel 6","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Rodeway Inn":{"tags":{"name":"Rodeway Inn","tourism":"motel"},"name":"Rodeway Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/museum/Heimatmuseum":{"tags":{"name":"Heimatmuseum","tourism":"museum"},"name":"Heimatmuseum","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Museum":{"tags":{"name":"Museum","tourism":"museum"},"name":"Museum","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Stadtmuseum":{"tags":{"name":"Stadtmuseum","tourism":"museum"},"name":"Stadtmuseum","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Tájház":{"tags":{"name":"Tájház","tourism":"museum"},"name":"Tájház","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Краеведческий музей":{"tags":{"name":"Краеведческий музей","tourism":"museum"},"name":"Краеведческий музей","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Музей":{"tags":{"name":"Музей","tourism":"museum"},"name":"Музей","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true}};
18638
18639 var defaults = {"area":["category-landuse","category-building","category-water-area","category-natural-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","category-natural-line","power/line","line"],"point":["category-natural-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","highway/turning_loop","traffic_calming","highway/mini_roundabout","highway/motorway_junction","vertex"],"relation":["category-route","category-restriction","type/boundary","type/multipolygon","type/site","relation"]};
18640
18641 var categories = {"category-barrier":{"icon":"roadblock","geometry":"line","name":"Barrier Features","members":["barrier/fence","barrier/wall","barrier/ditch","barrier/gate","barrier/hedge","barrier"]},"category-building":{"icon":"building","geometry":"area","name":"Building Features","members":["building","building/house","building/apartments","building/commercial","building/industrial","building/residential"]},"category-golf":{"icon":"golf","geometry":"area","name":"Golf Features","members":["golf/fairway","golf/green","golf/lateral_water_hazard_area","golf/rough","golf/bunker","golf/tee","golf/water_hazard_area"]},"category-landuse":{"icon":"landuse","geometry":"area","name":"Land Use Features","members":["landuse/residential","landuse/industrial","landuse/commercial","landuse/retail","landuse/farmland","landuse/farmyard","landuse/forest","landuse/meadow","landuse/aquaculture","landuse/cemetery","landuse/military"]},"category-natural-area":{"icon":"natural","geometry":"area","name":"Natural Features","members":["natural/water","natural/wood","natural/scrub","natural/wetland","natural/grassland","natural/heath","natural/bare_rock","natural/beach","natural/cave_entrance","natural/glacier"]},"category-natural-line":{"icon":"natural","geometry":"line","name":"Natural Features","members":["natural/coastline","natural/tree_row"]},"category-natural-point":{"icon":"natural","geometry":"point","name":"Natural Features","members":["natural/peak","natural/cliff","natural/beach","natural/cave_entrance"]},"category-path":{"icon":"category-path","geometry":"line","name":"Path Features","members":["footway/crosswalk","footway/sidewalk","highway/steps","highway/path","highway/footway","highway/cycleway","highway/bridleway","highway/pedestrian"]},"category-rail":{"icon":"category-rail","geometry":"line","name":"Rail Features","members":["railway/rail","railway/subway","railway/tram","railway/monorail","railway/disused","railway/abandoned"]},"category-restriction":{"icon":"restriction","geometry":"relation","name":"Restriction Features","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":{"icon":"category-roads","geometry":"line","name":"Road Features","members":["highway/residential","highway/motorway","highway/trunk","highway/primary","highway/secondary","highway/tertiary","highway/living_street","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":{"icon":"route","geometry":"relation","name":"Route Features","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":{"icon":"water","geometry":"area","name":"Water Features","members":["natural/water/lake","natural/water/pond","natural/water/reservoir","natural/water"]},"category-water-line":{"icon":"category-water","geometry":"line","name":"Water Features","members":["waterway/river","waterway/stream","waterway/canal","waterway/ditch","waterway/drain"]}};
18642
18643 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:block_number","addr:city","addr:block_number","addr:conscriptionnumber","addr:county","addr:country","addr:county","addr:district","addr:floor","addr:hamlet","addr:housename","addr:housenumber","addr:neighbourhood","addr:place","addr:postcode","addr:province","addr:quarter","addr:state","addr:street","addr:subdistrict","addr:suburb","addr:unit"],"reference":{"key":"addr"},"icon":"address","universal":true,"label":"Address","strings":{"placeholders":{"block_number":"Block Number","block_number!jp":"Block No.","city":"City","city!jp":"City/Town/Village/Tokyo Special Ward","city!vn":"City/Town","conscriptionnumber":"123","country":"Country","county":"County","county!jp":"District","district":"District","district!vn":"Arrondissement/Town/District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","housenumber!jp":"Building No./Lot No.","neighbourhood":"Neighbourhood","neighbourhood!jp":"Chōme/Aza/Koaza","place":"Place","postcode":"Postcode","province":"Province","province!jp":"Prefecture","quarter":"Quarter","quarter!jp":"Ōaza/Machi","state":"State","street":"Street","subdistrict":"Subdistrict","subdistrict!vn":"Ward/Commune/Townlet","suburb":"Suburb","suburb!jp":"Ward","unit":"Unit"}}},"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"},"animal_boarding":{"key":"animal_boarding","type":"semiCombo","label":"For Animals"},"animal_breeding":{"key":"animal_breeding","type":"semiCombo","label":"For Animals"},"animal_shelter":{"key":"animal_shelter","type":"semiCombo","label":"For Animals"},"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"},"bath/open_air":{"key":"bath:open_air","label":"Open Air","type":"check"},"bath/sand_bath":{"key":"bath:sand_bath","label":"Sand Bath","type":"check"},"bath/type":{"key":"bath:type","type":"combo","label":"Specialty","strings":{"options":{"onsen":"Japanese Onsen","foot_bath":"Foot Bath","hot_spring":"Hot Spring"}}},"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"},"bridge":{"key":"bridge","type":"typeCombo","label":"Type","placeholder":"Default"},"building_area":{"key":"building","type":"combo","default":"yes","geometry":"area","label":"Building"},"building":{"key":"building","type":"combo","label":"Building"},"bunker_type":{"key":"bunker_type","type":"combo","label":"Type"},"camera/direction":{"key":"camera:direction","type":"number","label":"Direction (Degrees Clockwise)","placeholder":"45, 90, 180, 270"},"camera/mount":{"key":"camera:mount","type":"combo","label":"Camera Mount"},"camera/type":{"key":"camera:type","type":"combo","label":"Camera Type","strings":{"options":{"fixed":"Fixed","panning":"Panning","dome":"Dome"}}},"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"}}},"castle_type":{"key":"castle_type","type":"combo","label":"Type"},"clock_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}}},"clothes":{"key":"clothes","type":"semiCombo","label":"Clothes"},"club":{"key":"club","type":"typeCombo","label":"Type"},"collection_times":{"key":"collection_times","type":"text","label":"Collection Times"},"comment":{"key":"comment","type":"textarea","label":"Changeset Comment","placeholder":"Brief description of your contributions (required)"},"communication_multi":{"key":"communication:","type":"multiCombo","label":"Communication Types"},"construction":{"key":"construction","type":"combo","label":"Type"},"contact/webcam":{"key":"contact:webcam","type":"url","icon":"website","label":"Webcam URL","placeholder":"http://example.com/"},"content":{"key":"content","type":"combo","label":"Content"},"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":"semiCombo","label":"Crops"},"crossing":{"key":"crossing","type":"combo","label":"Type"},"cuisine":{"key":"cuisine","type":"semiCombo","label":"Cuisines"},"currency_multi":{"key":"currency:","type":"multiCombo","label":"Currency Types"},"cutting":{"key":"cutting","type":"typeCombo","label":"Type","placeholder":"Default"},"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"},"email":{"key":"email","type":"email","placeholder":"example@example.com","universal":true,"label":"Email"},"embankment":{"key":"embankment","type":"typeCombo","label":"Type","placeholder":"Default"},"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","universal":true,"placeholder":"+31 42 123 4567"},"fee":{"key":"fee","type":"check","label":"Fee"},"fence_type":{"key":"fence_type","type":"combo","label":"Type"},"fire_hydrant/position":{"key":"fire_hydrant:position","type":"combo","label":"Position","strings":{"options":{"lane":"Lane","parking_lot":"Parking Lot","sidewalk":"Sidewalk","green":"Green"}}},"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},"ford":{"key":"ford","type":"typeCombo","label":"Type","placeholder":"Default"},"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/output/electricity":{"key":"generator:output:electricity","type":"text","label":"Power Output","placeholder":"50 MW, 100 MW, 200 MW..."},"generator/source":{"key":"generator:source","type":"combo","label":"Source"},"generator/type":{"key":"generator:type","type":"combo","label":"Type"},"grape_variety":{"key":"grape_variety","type":"semiCombo","label":"Grape Varieties"},"handicap":{"key":"handicap","type":"number","label":"Handicap","placeholder":"1-18"},"handrail":{"key":"handrail","type":"check","label":"Handrail"},"hashtags":{"key":"hashtags","type":"semiCombo","label":"Hashtags","placeholder":"#example"},"height":{"key":"height","type":"number","label":"Height (Meters)"},"highway":{"key":"highway","type":"typeCombo","label":"Type"},"historic":{"key":"historic","type":"typeCombo","label":"Type"},"historic/civilization":{"key":"historic:civilization","type":"combo","label":"Historic Civilization"},"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"},"inscription":{"key":"inscription","type":"textarea","label":"Inscription"},"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"},"internet_access/ssid":{"key":"internet_access:ssid","type":"text","label":"SSID (Network Name)"},"kerb":{"key":"kerb","type":"combo","label":"Curb"},"label":{"key":"label","type":"textarea","label":"Label"},"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":"number","label":"Layer","placeholder":"0"},"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"},"manhole":{"key":"manhole","type":"typeCombo","label":"Type"},"map_size":{"key":"map_size","type":"typeCombo","label":"Coverage"},"map_type":{"key":"map_type","type":"typeCombo","label":"Type"},"maxheight":{"key":"maxheight","type":"combo","label":"Max Height","placeholder":"4, 4.5, 5, 14'0\", 14'6\", 15'0\"","snake_case":false},"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},"maxweight":{"key":"maxweight","type":"combo","label":"Max Weight","snake_case":false},"milestone_position":{"key":"railway:position","type":"text","placeholder":"Distance to one decimal (123.4)","label":"Milestone Position"},"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","universal":true,"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":"onewayCheck","label":"One Way","strings":{"options":{"undefined":"Assumed to be Yes","yes":"Yes","no":"No"}}},"oneway":{"key":"oneway","type":"onewayCheck","label":"One Way","strings":{"options":{"undefined":"Assumed to be No","yes":"Yes","no":"No"}}},"opening_hours":{"key":"opening_hours","type":"combo","label":"Hours","snake_case":false},"operator":{"key":"operator","type":"text","label":"Operator"},"outdoor_seating":{"key":"outdoor_seating","type":"check","label":"Outdoor Seating"},"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"},"plant":{"key":"plant","type":"combo","label":"Plant"},"plant/output/electricity":{"key":"plant:output:electricity","type":"text","label":"Power Output","placeholder":"500 MW, 1000 MW, 2000 MW..."},"population":{"key":"population","type":"text","label":"Population"},"power_supply":{"key":"power_supply","type":"check","label":"Power Supply"},"power":{"key":"power","type":"typeCombo","label":"Type"},"produce":{"key":"produce","type":"semiCombo","label":"Produce"},"product":{"key":"product","type":"semiCombo","label":"Products"},"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_aeroway_gate":{"key":"ref","type":"text","label":"Gate Number"},"ref_golf_hole":{"key":"ref","type":"text","label":"Hole Number","placeholder":"1-18"},"ref_highway_junction":{"key":"ref","type":"text","label":"Junction Number"},"ref_platform":{"key":"ref","type":"text","label":"Platform Number"},"ref_road_number":{"key":"ref","type":"text","label":"Road Number"},"ref_route":{"key":"ref","type":"text","label":"Route Number"},"ref_runway":{"key":"ref","type":"text","label":"Runway Number","placeholder":"e.g. 01L/19R"},"ref_stop_position":{"key":"ref","type":"text","label":"Stop Number"},"ref_taxiway":{"key":"ref","type":"text","label":"Taxiway Name","placeholder":"e.g. A5"},"ref":{"key":"ref","type":"text","label":"Reference Code"},"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_times":{"key":"service_times","type":"text","label":"Service Times"},"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"},"service/vehicle":{"key":"service:vehicle:","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":"combo","label":"People Served"},"social_facility":{"key":"social_facility","type":"combo","label":"Type"},"source":{"key":"source","type":"semiCombo","icon":"source","universal":true,"label":"Sources","options":["survey","local knowledge","gps","aerial imagery","streetlevel imagery"]},"sport_ice":{"key":"sport","type":"semiCombo","label":"Sports","options":["skating","hockey","multi","curling","ice_stock"]},"sport_racing_motor":{"key":"sport","type":"semiCombo","label":"Sports","options":["motor","karting","motocross"]},"sport_racing_nonmotor":{"key":"sport","type":"semiCombo","label":"Sports","options":["bmx","cycling","dog_racing","horse_racing","running"]},"sport":{"key":"sport","type":"semiCombo","label":"Sports"},"stars":{"key":"stars","type":"number","label":"Stars"},"start_date":{"key":"start_date","type":"text","universal":true,"label":"Start Date"},"step_count":{"key":"step_count","type":"number","label":"Number of Steps"},"stop":{"key":"stop","type":"combo","label":"Stop Type","strings":{"options":{"all":"All Ways","minor":"Minor Road"}}},"structure":{"type":"structureRadio","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"},"surveillance":{"key":"surveillance","type":"combo","label":"Surveillance Kind"},"surveillance/type":{"key":"surveillance:type","type":"combo","label":"Surveillance Type","strings":{"options":{"camera":"Camera","guard":"Guard","ALPR":"Automatic License Plate Reader"}}},"surveillance/zone":{"key":"surveillance:zone","type":"combo","label":"Surveillance Zone"},"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"}}},"toll":{"key":"toll","type":"check","label":"Toll"},"tomb":{"key":"tomb","type":"typeCombo","label":"Type"},"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":"semiCombo","label":"Trees"},"tunnel_waterway":{"key":"tunnel","type":"combo","label":"Tunnel"},"tunnel":{"key":"tunnel","type":"typeCombo","label":"Type","placeholder":"Default"},"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)"}}},"wall":{"key":"wall","type":"combo","label":"Type"},"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"}};
18644
18645 var all = ["aerialway","airfield","airport","alcohol-shop","america-football","amusement-park","aquarium","art-gallery","attraction","bakery","bank","bar","barrier","baseball","basketball","bbq","beer","bicycle","bicycle-share","blood-bank","buddhism","building","building-alt1","bus","cafe","campsite","car","castle","cemetery","cinema","circle","circle-stroked","city","clothing-store","college","commercial","cricket","cross","dam","danger","defibrillator","dentist","doctor","dog-park","drinking-water","embassy","emergency-phone","entrance","entrance-alt1","farm","fast-food","fence","ferry","fire-station","florist","fuel","gaming","garden","garden-center","gift","golf","grocery","hairdresser","harbor","heart","heliport","home","horse-riding","hospital","ice-cream","industry","information","karaoke","landmark","landuse","laundry","library","lighthouse","lodging","logging","marker","marker-stroked","mobile-phone","monument","mountain","museum","music","natural","park","park-alt1","parking","parking-garage","pharmacy","picnic-site","pitch","place-of-worship","playground","police","post","prison","rail","rail-light","rail-metro","ranger-station","recycling","religious-christian","religious-jewish","religious-muslim","residential-community","restaurant","roadblock","rocket","school","scooter","shelter","shop","skiing","slaughterhouse","snowmobile","soccer","square","square-stroked","stadium","star","star-stroked","suitcase","sushi","swimming","teahouse","telephone","tennis","theatre","toilet","town","town-hall","triangle","triangle-stroked","veterinary","village","volcano","warehouse","waste-basket","water","wetland","wheelchair","zoo"];
18646 var all$1 = {
18647         all: all
18648 };
18649
18650 var all$2 = Object.freeze({
18651         all: all,
18652         default: all$1
18653 });
18654
18655 var Airport = ["airfield","airport","heliport","rocket"];
18656 var Dining = ["bakery","bar","beer","cafe","fast-food","ice-cream","restaurant"];
18657 var Education = ["college","school"];
18658 var General = ["alcohol-shop","amusement-park","aquarium","art-gallery","attraction","bank","bicycle","bicycle-share","car","castle","cinema","circle","circle-stroked","clothing-store","drinking-water","embassy","fire-station","fuel","grocery","harbor","information","laundry","library","lodging","marker","monument","museum","music","place-of-worship","police","post","prison","religious-christian","religious-jewish","religious-muslim","shop","stadium","star","suitcase","swimming","theatre","toilet","town-hall","triangle","triangle-stroked","veterinary"];
18659 var Health = ["dentist","doctor","hospital","pharmacy"];
18660 var Outdoors = ["campsite","cemetery","dog-park","garden","golf","park","picnic-site","playground","zoo"];
18661 var Transit = ["bus","ferry"];
18662 var streets = {
18663         Airport: Airport,
18664         Dining: Dining,
18665         Education: Education,
18666         General: General,
18667         Health: Health,
18668         Outdoors: Outdoors,
18669         Transit: Transit,
18670         "Mountain peak": ["mountain","volcano"],
18671         "Rail station": ["entrance","rail","rail-light","rail-metro"]
18672 };
18673
18674 var streets$1 = Object.freeze({
18675         Airport: Airport,
18676         Dining: Dining,
18677         Education: Education,
18678         General: General,
18679         Health: Health,
18680         Outdoors: Outdoors,
18681         Transit: Transit,
18682         default: streets
18683 });
18684
18685 var require$$0 = ( all$2 && all$1 ) || all$2;
18686
18687 var require$$1 = ( streets$1 && streets ) || streets$1;
18688
18689 var index$1 = {
18690   layouts: {
18691     all: require$$0,
18692     streets: require$$1
18693   }
18694 };
18695
18696 var dataFeatureIcons = index$1.layouts.all.all;
18697
18698 var data = {
18699     imagery: dataImagery,
18700     presets: {
18701         presets: presets,
18702         defaults: defaults,
18703         categories: categories,
18704         fields: fields
18705     }
18706 };
18707
18708 function osmEntity$$1(attrs) {
18709     // For prototypal inheritance.
18710     if (this instanceof osmEntity$$1) return;
18711
18712     // Create the appropriate subtype.
18713     if (attrs && attrs.type) {
18714         return osmEntity$$1[attrs.type].apply(this, arguments);
18715     } else if (attrs && attrs.id) {
18716         return osmEntity$$1[osmEntity$$1.id.type(attrs.id)].apply(this, arguments);
18717     }
18718
18719     // Initialize a generic Entity (used only in tests).
18720     return (new osmEntity$$1()).initialize(arguments);
18721 }
18722
18723
18724 osmEntity$$1.id = function(type) {
18725     return osmEntity$$1.id.fromOSM(type, osmEntity$$1.id.next[type]--);
18726 };
18727
18728
18729 osmEntity$$1.id.next = {
18730     changeset: -1, node: -1, way: -1, relation: -1
18731 };
18732
18733
18734 osmEntity$$1.id.fromOSM = function(type, id) {
18735     return type[0] + id;
18736 };
18737
18738
18739 osmEntity$$1.id.toOSM = function(id) {
18740     return id.slice(1);
18741 };
18742
18743
18744 osmEntity$$1.id.type = function(id) {
18745     return { 'c': 'changeset', 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
18746 };
18747
18748
18749 // A function suitable for use as the second argument to d3.selection#data().
18750 osmEntity$$1.key = function(entity) {
18751     return entity.id + 'v' + (entity.v || 0);
18752 };
18753
18754
18755 osmEntity$$1.prototype = {
18756
18757     tags: {},
18758
18759
18760     initialize: function(sources) {
18761         for (var i = 0; i < sources.length; ++i) {
18762             var source = sources[i];
18763             for (var prop in source) {
18764                 if (Object.prototype.hasOwnProperty.call(source, prop)) {
18765                     if (source[prop] === undefined) {
18766                         delete this[prop];
18767                     } else {
18768                         this[prop] = source[prop];
18769                     }
18770                 }
18771             }
18772         }
18773
18774         if (!this.id && this.type) {
18775             this.id = osmEntity$$1.id(this.type);
18776         }
18777         if (!this.hasOwnProperty('visible')) {
18778             this.visible = true;
18779         }
18780
18781         if (debug) {
18782             Object.freeze(this);
18783             Object.freeze(this.tags);
18784
18785             if (this.loc) Object.freeze(this.loc);
18786             if (this.nodes) Object.freeze(this.nodes);
18787             if (this.members) Object.freeze(this.members);
18788         }
18789
18790         return this;
18791     },
18792
18793
18794     copy: function(resolver, copies) {
18795         if (copies[this.id])
18796             return copies[this.id];
18797
18798         var copy = osmEntity$$1(this, {id: undefined, user: undefined, version: undefined});
18799         copies[this.id] = copy;
18800
18801         return copy;
18802     },
18803
18804
18805     osmId: function() {
18806         return osmEntity$$1.id.toOSM(this.id);
18807     },
18808
18809
18810     isNew: function() {
18811         return this.osmId() < 0;
18812     },
18813
18814
18815     update: function(attrs) {
18816         return osmEntity$$1(this, attrs, {v: 1 + (this.v || 0)});
18817     },
18818
18819
18820     mergeTags: function(tags) {
18821         var merged = lodash.clone(this.tags), changed = false;
18822         for (var k in tags) {
18823             var t1 = merged[k],
18824                 t2 = tags[k];
18825             if (!t1) {
18826                 changed = true;
18827                 merged[k] = t2;
18828             } else if (t1 !== t2) {
18829                 changed = true;
18830                 merged[k] = lodash.union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
18831             }
18832         }
18833         return changed ? this.update({tags: merged}) : this;
18834     },
18835
18836
18837     intersects: function(extent, resolver) {
18838         return this.extent(resolver).intersects(extent);
18839     },
18840
18841
18842     isUsed: function(resolver) {
18843         return lodash.without(Object.keys(this.tags), 'area').length > 0 ||
18844             resolver.parentRelations(this).length > 0;
18845     },
18846
18847
18848     hasInterestingTags: function() {
18849         return lodash.keys(this.tags).some(osmIsInterestingTag);
18850     },
18851
18852
18853     isHighwayIntersection: function() {
18854         return false;
18855     },
18856
18857     isDegenerate: function() {
18858         return true;
18859     },
18860
18861     deprecatedTags: function() {
18862         var tags = lodash.toPairs(this.tags);
18863         var deprecated = {};
18864
18865         dataDeprecated.forEach(function(d) {
18866             var match = lodash.toPairs(d.old)[0];
18867             tags.forEach(function(t) {
18868                 if (t[0] === match[0] &&
18869                     (t[1] === match[1] || match[1] === '*')) {
18870                     deprecated[t[0]] = t[1];
18871                 }
18872             });
18873         });
18874
18875         return deprecated;
18876     }
18877 };
18878
18879 function geoRoundCoords(c) {
18880     return [Math.floor(c[0]), Math.floor(c[1])];
18881 }
18882
18883
18884 function geoInterp(p1, p2, t) {
18885     return [p1[0] + (p2[0] - p1[0]) * t,
18886             p1[1] + (p2[1] - p1[1]) * t];
18887 }
18888
18889
18890 // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
18891 // Returns a positive value, if OAB makes a counter-clockwise turn,
18892 // negative for clockwise turn, and zero if the points are collinear.
18893 function geoCross(o, a, b) {
18894     return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
18895 }
18896
18897
18898 // http://jsperf.com/id-dist-optimization
18899 function geoEuclideanDistance(a, b) {
18900     var x = a[0] - b[0], y = a[1] - b[1];
18901     return Math.sqrt((x * x) + (y * y));
18902 }
18903
18904
18905 // using WGS84 polar radius (6356752.314245179 m)
18906 // const = 2 * PI * r / 360
18907 function geoLatToMeters(dLat) {
18908     return dLat * 110946.257617;
18909 }
18910
18911
18912 // using WGS84 equatorial radius (6378137.0 m)
18913 // const = 2 * PI * r / 360
18914 function geoLonToMeters(dLon, atLat) {
18915     return Math.abs(atLat) >= 90 ? 0 :
18916         dLon * 111319.490793 * Math.abs(Math.cos(atLat * (Math.PI/180)));
18917 }
18918
18919
18920 // using WGS84 polar radius (6356752.314245179 m)
18921 // const = 2 * PI * r / 360
18922 function geoMetersToLat(m) {
18923     return m / 110946.257617;
18924 }
18925
18926
18927 // using WGS84 equatorial radius (6378137.0 m)
18928 // const = 2 * PI * r / 360
18929 function geoMetersToLon(m, atLat) {
18930     return Math.abs(atLat) >= 90 ? 0 :
18931         m / 111319.490793 / Math.abs(Math.cos(atLat * (Math.PI/180)));
18932 }
18933
18934
18935 function geoOffsetToMeters(offset) {
18936     var equatRadius = 6356752.314245179,
18937         polarRadius = 6378137.0,
18938         tileSize = 256;
18939
18940     return [
18941         offset[0] * 2 * Math.PI * equatRadius / tileSize,
18942         -offset[1] * 2 * Math.PI * polarRadius / tileSize
18943     ];
18944 }
18945
18946
18947 function geoMetersToOffset(meters) {
18948     var equatRadius = 6356752.314245179,
18949         polarRadius = 6378137.0,
18950         tileSize = 256;
18951
18952     return [
18953         meters[0] * tileSize / (2 * Math.PI * equatRadius),
18954         -meters[1] * tileSize / (2 * Math.PI * polarRadius)
18955     ];
18956 }
18957
18958
18959 // Equirectangular approximation of spherical distances on Earth
18960 function geoSphericalDistance(a, b) {
18961     var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2),
18962         y = geoLatToMeters(a[1] - b[1]);
18963     return Math.sqrt((x * x) + (y * y));
18964 }
18965
18966
18967 function geoEdgeEqual(a, b) {
18968     return (a[0] === b[0] && a[1] === b[1]) ||
18969         (a[0] === b[1] && a[1] === b[0]);
18970 }
18971
18972
18973 // Return the counterclockwise angle in the range (-pi, pi)
18974 // between the positive X axis and the line intersecting a and b.
18975 function geoAngle(a, b, projection) {
18976     a = projection(a.loc);
18977     b = projection(b.loc);
18978     return Math.atan2(b[1] - a[1], b[0] - a[0]);
18979 }
18980
18981
18982 // Rotate all points counterclockwise around a pivot point by given angle
18983 function geoRotate(points, angle, around) {
18984     return points.map(function(point) {
18985         var radial = [point[0] - around[0], point[1] - around[1]];
18986         return [
18987             radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + around[0],
18988             radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + around[1]
18989         ];
18990     });
18991 }
18992
18993
18994 // Choose the edge with the minimal distance from `point` to its orthogonal
18995 // projection onto that edge, if such a projection exists, or the distance to
18996 // the closest vertex on that edge. Returns an object with the `index` of the
18997 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
18998 function geoChooseEdge(nodes, point, projection) {
18999     var dist = geoEuclideanDistance,
19000         points = nodes.map(function(n) { return projection(n.loc); }),
19001         min = Infinity,
19002         idx, loc;
19003
19004     function dot(p, q) {
19005         return p[0] * q[0] + p[1] * q[1];
19006     }
19007
19008     for (var i = 0; i < points.length - 1; i++) {
19009         var o = points[i],
19010             s = [points[i + 1][0] - o[0],
19011                  points[i + 1][1] - o[1]],
19012             v = [point[0] - o[0],
19013                  point[1] - o[1]],
19014             proj = dot(v, s) / dot(s, s),
19015             p;
19016
19017         if (proj < 0) {
19018             p = o;
19019         } else if (proj > 1) {
19020             p = points[i + 1];
19021         } else {
19022             p = [o[0] + proj * s[0], o[1] + proj * s[1]];
19023         }
19024
19025         var d = dist(p, point);
19026         if (d < min) {
19027             min = d;
19028             idx = i + 1;
19029             loc = projection.invert(p);
19030         }
19031     }
19032
19033     return {
19034         index: idx,
19035         distance: min,
19036         loc: loc
19037     };
19038 }
19039
19040
19041 // Return the intersection point of 2 line segments.
19042 // From https://github.com/pgkelley4/line-segments-intersect
19043 // This uses the vector cross product approach described below:
19044 //  http://stackoverflow.com/a/565282/786339
19045 function geoLineIntersection(a, b) {
19046     function subtractPoints(point1, point2) {
19047         return [point1[0] - point2[0], point1[1] - point2[1]];
19048     }
19049     function crossProduct(point1, point2) {
19050         return point1[0] * point2[1] - point1[1] * point2[0];
19051     }
19052
19053     var p = [a[0][0], a[0][1]],
19054         p2 = [a[1][0], a[1][1]],
19055         q = [b[0][0], b[0][1]],
19056         q2 = [b[1][0], b[1][1]],
19057         r = subtractPoints(p2, p),
19058         s = subtractPoints(q2, q),
19059         uNumerator = crossProduct(subtractPoints(q, p), r),
19060         denominator = crossProduct(r, s);
19061
19062     if (uNumerator && denominator) {
19063         var u = uNumerator / denominator,
19064             t = crossProduct(subtractPoints(q, p), s) / denominator;
19065
19066         if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
19067             return geoInterp(p, p2, t);
19068         }
19069     }
19070
19071     return null;
19072 }
19073
19074
19075 function geoPathIntersections(path1, path2) {
19076     var intersections = [];
19077     for (var i = 0; i < path1.length - 1; i++) {
19078         for (var j = 0; j < path2.length - 1; j++) {
19079             var a = [ path1[i], path1[i+1] ],
19080                 b = [ path2[j], path2[j+1] ],
19081                 hit = geoLineIntersection(a, b);
19082             if (hit) intersections.push(hit);
19083         }
19084     }
19085     return intersections;
19086 }
19087
19088
19089 // Return whether point is contained in polygon.
19090 //
19091 // `point` should be a 2-item array of coordinates.
19092 // `polygon` should be an array of 2-item arrays of coordinates.
19093 //
19094 // From https://github.com/substack/point-in-polygon.
19095 // ray-casting algorithm based on
19096 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
19097 //
19098 function geoPointInPolygon(point, polygon) {
19099     var x = point[0],
19100         y = point[1],
19101         inside = false;
19102
19103     for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
19104         var xi = polygon[i][0], yi = polygon[i][1];
19105         var xj = polygon[j][0], yj = polygon[j][1];
19106
19107         var intersect = ((yi > y) !== (yj > y)) &&
19108             (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
19109         if (intersect) inside = !inside;
19110     }
19111
19112     return inside;
19113 }
19114
19115
19116 function geoPolygonContainsPolygon(outer, inner) {
19117     return lodash.every(inner, function(point) {
19118         return geoPointInPolygon(point, outer);
19119     });
19120 }
19121
19122
19123 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
19124     function testSegments(outer, inner) {
19125         for (var i = 0; i < outer.length - 1; i++) {
19126             for (var j = 0; j < inner.length - 1; j++) {
19127                 var a = [ outer[i], outer[i+1] ],
19128                     b = [ inner[j], inner[j+1] ];
19129                 if (geoLineIntersection(a, b)) return true;
19130             }
19131         }
19132         return false;
19133     }
19134
19135     function testPoints(outer, inner) {
19136         return lodash.some(inner, function(point) {
19137             return geoPointInPolygon(point, outer);
19138         });
19139     }
19140
19141    return testPoints(outer, inner) || (!!checkSegments && testSegments(outer, inner));
19142 }
19143
19144
19145 function geoPathLength(path) {
19146     var length = 0;
19147     for (var i = 0; i < path.length - 1; i++) {
19148         length += geoEuclideanDistance(path[i], path[i + 1]);
19149     }
19150     return length;
19151 }
19152
19153 function geoExtent$$1(min, max) {
19154     if (!(this instanceof geoExtent$$1)) return new geoExtent$$1(min, max);
19155     if (min instanceof geoExtent$$1) {
19156         return min;
19157     } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
19158         this[0] = min[0];
19159         this[1] = min[1];
19160     } else {
19161         this[0] = min        || [ Infinity,  Infinity];
19162         this[1] = max || min || [-Infinity, -Infinity];
19163     }
19164 }
19165
19166 geoExtent$$1.prototype = new Array(2);
19167
19168 lodash.extend(geoExtent$$1.prototype, {
19169
19170     equals: function (obj) {
19171         return this[0][0] === obj[0][0] &&
19172             this[0][1] === obj[0][1] &&
19173             this[1][0] === obj[1][0] &&
19174             this[1][1] === obj[1][1];
19175     },
19176
19177
19178     extend: function(obj) {
19179         if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19180         return geoExtent$$1(
19181             [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
19182             [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
19183         );
19184     },
19185
19186
19187     _extend: function(extent) {
19188         this[0][0] = Math.min(extent[0][0], this[0][0]);
19189         this[0][1] = Math.min(extent[0][1], this[0][1]);
19190         this[1][0] = Math.max(extent[1][0], this[1][0]);
19191         this[1][1] = Math.max(extent[1][1], this[1][1]);
19192     },
19193
19194
19195     area: function() {
19196         return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
19197     },
19198
19199
19200     center: function() {
19201         return [(this[0][0] + this[1][0]) / 2,
19202                 (this[0][1] + this[1][1]) / 2];
19203     },
19204
19205
19206     rectangle: function() {
19207         return [this[0][0], this[0][1], this[1][0], this[1][1]];
19208     },
19209
19210
19211     bbox: function() {
19212         return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
19213     },
19214
19215
19216     polygon: function() {
19217         return [
19218             [this[0][0], this[0][1]],
19219             [this[0][0], this[1][1]],
19220             [this[1][0], this[1][1]],
19221             [this[1][0], this[0][1]],
19222             [this[0][0], this[0][1]]
19223         ];
19224     },
19225
19226
19227     contains: function(obj) {
19228         if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19229         return obj[0][0] >= this[0][0] &&
19230                obj[0][1] >= this[0][1] &&
19231                obj[1][0] <= this[1][0] &&
19232                obj[1][1] <= this[1][1];
19233     },
19234
19235
19236     intersects: function(obj) {
19237         if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19238         return obj[0][0] <= this[1][0] &&
19239                obj[0][1] <= this[1][1] &&
19240                obj[1][0] >= this[0][0] &&
19241                obj[1][1] >= this[0][1];
19242     },
19243
19244
19245     intersection: function(obj) {
19246         if (!this.intersects(obj)) return new geoExtent$$1();
19247         return new geoExtent$$1(
19248             [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
19249             [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
19250         );
19251     },
19252
19253
19254     percentContainedIn: function(obj) {
19255         if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19256         var a1 = this.intersection(obj).area(),
19257             a2 = this.area();
19258
19259         if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
19260             return 0;
19261         } else {
19262             return a1 / a2;
19263         }
19264     },
19265
19266
19267     padByMeters: function(meters) {
19268         var dLat = geoMetersToLat(meters),
19269             dLon = geoMetersToLon(meters, this.center()[1]);
19270         return geoExtent$$1(
19271             [this[0][0] - dLon, this[0][1] - dLat],
19272             [this[1][0] + dLon, this[1][1] + dLat]
19273         );
19274     },
19275
19276
19277     toParam: function() {
19278         return this.rectangle().join(',');
19279     }
19280
19281 });
19282
19283 var version = "4.10.0";
19284
19285 var ascending = function(a, b) {
19286   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
19287 };
19288
19289 var bisector = function(compare) {
19290   if (compare.length === 1) compare = ascendingComparator(compare);
19291   return {
19292     left: function(a, x, lo, hi) {
19293       if (lo == null) lo = 0;
19294       if (hi == null) hi = a.length;
19295       while (lo < hi) {
19296         var mid = lo + hi >>> 1;
19297         if (compare(a[mid], x) < 0) lo = mid + 1;
19298         else hi = mid;
19299       }
19300       return lo;
19301     },
19302     right: function(a, x, lo, hi) {
19303       if (lo == null) lo = 0;
19304       if (hi == null) hi = a.length;
19305       while (lo < hi) {
19306         var mid = lo + hi >>> 1;
19307         if (compare(a[mid], x) > 0) hi = mid;
19308         else lo = mid + 1;
19309       }
19310       return lo;
19311     }
19312   };
19313 };
19314
19315 function ascendingComparator(f) {
19316   return function(d, x) {
19317     return ascending(f(d), x);
19318   };
19319 }
19320
19321 var ascendingBisect = bisector(ascending);
19322 var bisectRight = ascendingBisect.right;
19323 var bisectLeft = ascendingBisect.left;
19324
19325 var pairs = function(array, f) {
19326   if (f == null) f = pair;
19327   var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
19328   while (i < n) pairs[i] = f(p, p = array[++i]);
19329   return pairs;
19330 };
19331
19332 function pair(a, b) {
19333   return [a, b];
19334 }
19335
19336 var cross = function(values0, values1, reduce) {
19337   var n0 = values0.length,
19338       n1 = values1.length,
19339       values = new Array(n0 * n1),
19340       i0,
19341       i1,
19342       i,
19343       value0;
19344
19345   if (reduce == null) reduce = pair;
19346
19347   for (i0 = i = 0; i0 < n0; ++i0) {
19348     for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {
19349       values[i] = reduce(value0, values1[i1]);
19350     }
19351   }
19352
19353   return values;
19354 };
19355
19356 var descending = function(a, b) {
19357   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
19358 };
19359
19360 var number = function(x) {
19361   return x === null ? NaN : +x;
19362 };
19363
19364 var variance = function(values, valueof) {
19365   var n = values.length,
19366       m = 0,
19367       i = -1,
19368       mean = 0,
19369       value,
19370       delta,
19371       sum = 0;
19372
19373   if (valueof == null) {
19374     while (++i < n) {
19375       if (!isNaN(value = number(values[i]))) {
19376         delta = value - mean;
19377         mean += delta / ++m;
19378         sum += delta * (value - mean);
19379       }
19380     }
19381   }
19382
19383   else {
19384     while (++i < n) {
19385       if (!isNaN(value = number(valueof(values[i], i, values)))) {
19386         delta = value - mean;
19387         mean += delta / ++m;
19388         sum += delta * (value - mean);
19389       }
19390     }
19391   }
19392
19393   if (m > 1) return sum / (m - 1);
19394 };
19395
19396 var deviation = function(array, f) {
19397   var v = variance(array, f);
19398   return v ? Math.sqrt(v) : v;
19399 };
19400
19401 var extent = function(values, valueof) {
19402   var n = values.length,
19403       i = -1,
19404       value,
19405       min,
19406       max;
19407
19408   if (valueof == null) {
19409     while (++i < n) { // Find the first comparable value.
19410       if ((value = values[i]) != null && value >= value) {
19411         min = max = value;
19412         while (++i < n) { // Compare the remaining values.
19413           if ((value = values[i]) != null) {
19414             if (min > value) min = value;
19415             if (max < value) max = value;
19416           }
19417         }
19418       }
19419     }
19420   }
19421
19422   else {
19423     while (++i < n) { // Find the first comparable value.
19424       if ((value = valueof(values[i], i, values)) != null && value >= value) {
19425         min = max = value;
19426         while (++i < n) { // Compare the remaining values.
19427           if ((value = valueof(values[i], i, values)) != null) {
19428             if (min > value) min = value;
19429             if (max < value) max = value;
19430           }
19431         }
19432       }
19433     }
19434   }
19435
19436   return [min, max];
19437 };
19438
19439 var array = Array.prototype;
19440
19441 var slice = array.slice;
19442 var map = array.map;
19443
19444 var constant = function(x) {
19445   return function() {
19446     return x;
19447   };
19448 };
19449
19450 var identity = function(x) {
19451   return x;
19452 };
19453
19454 var sequence = function(start, stop, step) {
19455   start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
19456
19457   var i = -1,
19458       n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
19459       range = new Array(n);
19460
19461   while (++i < n) {
19462     range[i] = start + i * step;
19463   }
19464
19465   return range;
19466 };
19467
19468 var e10 = Math.sqrt(50);
19469 var e5 = Math.sqrt(10);
19470 var e2 = Math.sqrt(2);
19471
19472 var ticks = function(start, stop, count) {
19473   var reverse = stop < start,
19474       i = -1,
19475       n,
19476       ticks,
19477       step;
19478
19479   if (reverse) n = start, start = stop, stop = n;
19480
19481   if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
19482
19483   if (step > 0) {
19484     start = Math.ceil(start / step);
19485     stop = Math.floor(stop / step);
19486     ticks = new Array(n = Math.ceil(stop - start + 1));
19487     while (++i < n) ticks[i] = (start + i) * step;
19488   } else {
19489     start = Math.floor(start * step);
19490     stop = Math.ceil(stop * step);
19491     ticks = new Array(n = Math.ceil(start - stop + 1));
19492     while (++i < n) ticks[i] = (start - i) / step;
19493   }
19494
19495   if (reverse) ticks.reverse();
19496
19497   return ticks;
19498 };
19499
19500 function tickIncrement(start, stop, count) {
19501   var step = (stop - start) / Math.max(0, count),
19502       power = Math.floor(Math.log(step) / Math.LN10),
19503       error = step / Math.pow(10, power);
19504   return power >= 0
19505       ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
19506       : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
19507 }
19508
19509 function tickStep(start, stop, count) {
19510   var step0 = Math.abs(stop - start) / Math.max(0, count),
19511       step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
19512       error = step0 / step1;
19513   if (error >= e10) step1 *= 10;
19514   else if (error >= e5) step1 *= 5;
19515   else if (error >= e2) step1 *= 2;
19516   return stop < start ? -step1 : step1;
19517 }
19518
19519 var sturges = function(values) {
19520   return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
19521 };
19522
19523 var histogram = function() {
19524   var value = identity,
19525       domain = extent,
19526       threshold = sturges;
19527
19528   function histogram(data) {
19529     var i,
19530         n = data.length,
19531         x,
19532         values = new Array(n);
19533
19534     for (i = 0; i < n; ++i) {
19535       values[i] = value(data[i], i, data);
19536     }
19537
19538     var xz = domain(values),
19539         x0 = xz[0],
19540         x1 = xz[1],
19541         tz = threshold(values, x0, x1);
19542
19543     // Convert number of thresholds into uniform thresholds.
19544     if (!Array.isArray(tz)) {
19545       tz = tickStep(x0, x1, tz);
19546       tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive
19547     }
19548
19549     // Remove any thresholds outside the domain.
19550     var m = tz.length;
19551     while (tz[0] <= x0) tz.shift(), --m;
19552     while (tz[m - 1] > x1) tz.pop(), --m;
19553
19554     var bins = new Array(m + 1),
19555         bin;
19556
19557     // Initialize bins.
19558     for (i = 0; i <= m; ++i) {
19559       bin = bins[i] = [];
19560       bin.x0 = i > 0 ? tz[i - 1] : x0;
19561       bin.x1 = i < m ? tz[i] : x1;
19562     }
19563
19564     // Assign data to bins by value, ignoring any outside the domain.
19565     for (i = 0; i < n; ++i) {
19566       x = values[i];
19567       if (x0 <= x && x <= x1) {
19568         bins[bisectRight(tz, x, 0, m)].push(data[i]);
19569       }
19570     }
19571
19572     return bins;
19573   }
19574
19575   histogram.value = function(_) {
19576     return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value;
19577   };
19578
19579   histogram.domain = function(_) {
19580     return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain;
19581   };
19582
19583   histogram.thresholds = function(_) {
19584     return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;
19585   };
19586
19587   return histogram;
19588 };
19589
19590 var threshold = function(values, p, valueof) {
19591   if (valueof == null) valueof = number;
19592   if (!(n = values.length)) return;
19593   if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);
19594   if (p >= 1) return +valueof(values[n - 1], n - 1, values);
19595   var n,
19596       i = (n - 1) * p,
19597       i0 = Math.floor(i),
19598       value0 = +valueof(values[i0], i0, values),
19599       value1 = +valueof(values[i0 + 1], i0 + 1, values);
19600   return value0 + (value1 - value0) * (i - i0);
19601 };
19602
19603 var freedmanDiaconis = function(values, min, max) {
19604   values = map.call(values, number).sort(ascending);
19605   return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
19606 };
19607
19608 var scott = function(values, min, max) {
19609   return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
19610 };
19611
19612 var max = function(values, valueof) {
19613   var n = values.length,
19614       i = -1,
19615       value,
19616       max;
19617
19618   if (valueof == null) {
19619     while (++i < n) { // Find the first comparable value.
19620       if ((value = values[i]) != null && value >= value) {
19621         max = value;
19622         while (++i < n) { // Compare the remaining values.
19623           if ((value = values[i]) != null && value > max) {
19624             max = value;
19625           }
19626         }
19627       }
19628     }
19629   }
19630
19631   else {
19632     while (++i < n) { // Find the first comparable value.
19633       if ((value = valueof(values[i], i, values)) != null && value >= value) {
19634         max = value;
19635         while (++i < n) { // Compare the remaining values.
19636           if ((value = valueof(values[i], i, values)) != null && value > max) {
19637             max = value;
19638           }
19639         }
19640       }
19641     }
19642   }
19643
19644   return max;
19645 };
19646
19647 var mean = function(values, valueof) {
19648   var n = values.length,
19649       m = n,
19650       i = -1,
19651       value,
19652       sum = 0;
19653
19654   if (valueof == null) {
19655     while (++i < n) {
19656       if (!isNaN(value = number(values[i]))) sum += value;
19657       else --m;
19658     }
19659   }
19660
19661   else {
19662     while (++i < n) {
19663       if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;
19664       else --m;
19665     }
19666   }
19667
19668   if (m) return sum / m;
19669 };
19670
19671 var median = function(values, valueof) {
19672   var n = values.length,
19673       i = -1,
19674       value,
19675       numbers = [];
19676
19677   if (valueof == null) {
19678     while (++i < n) {
19679       if (!isNaN(value = number(values[i]))) {
19680         numbers.push(value);
19681       }
19682     }
19683   }
19684
19685   else {
19686     while (++i < n) {
19687       if (!isNaN(value = number(valueof(values[i], i, values)))) {
19688         numbers.push(value);
19689       }
19690     }
19691   }
19692
19693   return threshold(numbers.sort(ascending), 0.5);
19694 };
19695
19696 var merge = function(arrays) {
19697   var n = arrays.length,
19698       m,
19699       i = -1,
19700       j = 0,
19701       merged,
19702       array;
19703
19704   while (++i < n) j += arrays[i].length;
19705   merged = new Array(j);
19706
19707   while (--n >= 0) {
19708     array = arrays[n];
19709     m = array.length;
19710     while (--m >= 0) {
19711       merged[--j] = array[m];
19712     }
19713   }
19714
19715   return merged;
19716 };
19717
19718 var min = function(values, valueof) {
19719   var n = values.length,
19720       i = -1,
19721       value,
19722       min;
19723
19724   if (valueof == null) {
19725     while (++i < n) { // Find the first comparable value.
19726       if ((value = values[i]) != null && value >= value) {
19727         min = value;
19728         while (++i < n) { // Compare the remaining values.
19729           if ((value = values[i]) != null && min > value) {
19730             min = value;
19731           }
19732         }
19733       }
19734     }
19735   }
19736
19737   else {
19738     while (++i < n) { // Find the first comparable value.
19739       if ((value = valueof(values[i], i, values)) != null && value >= value) {
19740         min = value;
19741         while (++i < n) { // Compare the remaining values.
19742           if ((value = valueof(values[i], i, values)) != null && min > value) {
19743             min = value;
19744           }
19745         }
19746       }
19747     }
19748   }
19749
19750   return min;
19751 };
19752
19753 var permute = function(array, indexes) {
19754   var i = indexes.length, permutes = new Array(i);
19755   while (i--) permutes[i] = array[indexes[i]];
19756   return permutes;
19757 };
19758
19759 var scan = function(values, compare) {
19760   if (!(n = values.length)) return;
19761   var n,
19762       i = 0,
19763       j = 0,
19764       xi,
19765       xj = values[j];
19766
19767   if (compare == null) compare = ascending;
19768
19769   while (++i < n) {
19770     if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {
19771       xj = xi, j = i;
19772     }
19773   }
19774
19775   if (compare(xj, xj) === 0) return j;
19776 };
19777
19778 var shuffle = function(array, i0, i1) {
19779   var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
19780       t,
19781       i;
19782
19783   while (m) {
19784     i = Math.random() * m-- | 0;
19785     t = array[m + i0];
19786     array[m + i0] = array[i + i0];
19787     array[i + i0] = t;
19788   }
19789
19790   return array;
19791 };
19792
19793 var sum = function(values, valueof) {
19794   var n = values.length,
19795       i = -1,
19796       value,
19797       sum = 0;
19798
19799   if (valueof == null) {
19800     while (++i < n) {
19801       if (value = +values[i]) sum += value; // Note: zero and null are equivalent.
19802     }
19803   }
19804
19805   else {
19806     while (++i < n) {
19807       if (value = +valueof(values[i], i, values)) sum += value;
19808     }
19809   }
19810
19811   return sum;
19812 };
19813
19814 var transpose = function(matrix) {
19815   if (!(n = matrix.length)) return [];
19816   for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
19817     for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
19818       row[j] = matrix[j][i];
19819     }
19820   }
19821   return transpose;
19822 };
19823
19824 function length(d) {
19825   return d.length;
19826 }
19827
19828 var zip = function() {
19829   return transpose(arguments);
19830 };
19831
19832 var slice$1 = Array.prototype.slice;
19833
19834 var identity$1 = function(x) {
19835   return x;
19836 };
19837
19838 var top = 1;
19839 var right = 2;
19840 var bottom = 3;
19841 var left = 4;
19842 var epsilon = 1e-6;
19843
19844 function translateX(x) {
19845   return "translate(" + (x + 0.5) + ",0)";
19846 }
19847
19848 function translateY(y) {
19849   return "translate(0," + (y + 0.5) + ")";
19850 }
19851
19852 function number$1(scale) {
19853   return function(d) {
19854     return +scale(d);
19855   };
19856 }
19857
19858 function center(scale) {
19859   var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.
19860   if (scale.round()) offset = Math.round(offset);
19861   return function(d) {
19862     return +scale(d) + offset;
19863   };
19864 }
19865
19866 function entering() {
19867   return !this.__axis;
19868 }
19869
19870 function axis(orient, scale) {
19871   var tickArguments = [],
19872       tickValues = null,
19873       tickFormat = null,
19874       tickSizeInner = 6,
19875       tickSizeOuter = 6,
19876       tickPadding = 3,
19877       k = orient === top || orient === left ? -1 : 1,
19878       x = orient === left || orient === right ? "x" : "y",
19879       transform = orient === top || orient === bottom ? translateX : translateY;
19880
19881   function axis(context) {
19882     var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
19883         format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,
19884         spacing = Math.max(tickSizeInner, 0) + tickPadding,
19885         range = scale.range(),
19886         range0 = +range[0] + 0.5,
19887         range1 = +range[range.length - 1] + 0.5,
19888         position = (scale.bandwidth ? center : number$1)(scale.copy()),
19889         selection = context.selection ? context.selection() : context,
19890         path = selection.selectAll(".domain").data([null]),
19891         tick = selection.selectAll(".tick").data(values, scale).order(),
19892         tickExit = tick.exit(),
19893         tickEnter = tick.enter().append("g").attr("class", "tick"),
19894         line = tick.select("line"),
19895         text = tick.select("text");
19896
19897     path = path.merge(path.enter().insert("path", ".tick")
19898         .attr("class", "domain")
19899         .attr("stroke", "#000"));
19900
19901     tick = tick.merge(tickEnter);
19902
19903     line = line.merge(tickEnter.append("line")
19904         .attr("stroke", "#000")
19905         .attr(x + "2", k * tickSizeInner));
19906
19907     text = text.merge(tickEnter.append("text")
19908         .attr("fill", "#000")
19909         .attr(x, k * spacing)
19910         .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
19911
19912     if (context !== selection) {
19913       path = path.transition(context);
19914       tick = tick.transition(context);
19915       line = line.transition(context);
19916       text = text.transition(context);
19917
19918       tickExit = tickExit.transition(context)
19919           .attr("opacity", epsilon)
19920           .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
19921
19922       tickEnter
19923           .attr("opacity", epsilon)
19924           .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
19925     }
19926
19927     tickExit.remove();
19928
19929     path
19930         .attr("d", orient === left || orient == right
19931             ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
19932             : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
19933
19934     tick
19935         .attr("opacity", 1)
19936         .attr("transform", function(d) { return transform(position(d)); });
19937
19938     line
19939         .attr(x + "2", k * tickSizeInner);
19940
19941     text
19942         .attr(x, k * spacing)
19943         .text(format);
19944
19945     selection.filter(entering)
19946         .attr("fill", "none")
19947         .attr("font-size", 10)
19948         .attr("font-family", "sans-serif")
19949         .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
19950
19951     selection
19952         .each(function() { this.__axis = position; });
19953   }
19954
19955   axis.scale = function(_) {
19956     return arguments.length ? (scale = _, axis) : scale;
19957   };
19958
19959   axis.ticks = function() {
19960     return tickArguments = slice$1.call(arguments), axis;
19961   };
19962
19963   axis.tickArguments = function(_) {
19964     return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();
19965   };
19966
19967   axis.tickValues = function(_) {
19968     return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();
19969   };
19970
19971   axis.tickFormat = function(_) {
19972     return arguments.length ? (tickFormat = _, axis) : tickFormat;
19973   };
19974
19975   axis.tickSize = function(_) {
19976     return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
19977   };
19978
19979   axis.tickSizeInner = function(_) {
19980     return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
19981   };
19982
19983   axis.tickSizeOuter = function(_) {
19984     return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
19985   };
19986
19987   axis.tickPadding = function(_) {
19988     return arguments.length ? (tickPadding = +_, axis) : tickPadding;
19989   };
19990
19991   return axis;
19992 }
19993
19994 function axisTop(scale) {
19995   return axis(top, scale);
19996 }
19997
19998 function axisRight(scale) {
19999   return axis(right, scale);
20000 }
20001
20002 function axisBottom(scale) {
20003   return axis(bottom, scale);
20004 }
20005
20006 function axisLeft(scale) {
20007   return axis(left, scale);
20008 }
20009
20010 var noop = {value: function() {}};
20011
20012 function dispatch() {
20013   for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
20014     if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
20015     _[t] = [];
20016   }
20017   return new Dispatch(_);
20018 }
20019
20020 function Dispatch(_) {
20021   this._ = _;
20022 }
20023
20024 function parseTypenames(typenames, types) {
20025   return typenames.trim().split(/^|\s+/).map(function(t) {
20026     var name = "", i = t.indexOf(".");
20027     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
20028     if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
20029     return {type: t, name: name};
20030   });
20031 }
20032
20033 Dispatch.prototype = dispatch.prototype = {
20034   constructor: Dispatch,
20035   on: function(typename, callback) {
20036     var _ = this._,
20037         T = parseTypenames(typename + "", _),
20038         t,
20039         i = -1,
20040         n = T.length;
20041
20042     // If no callback was specified, return the callback of the given type and name.
20043     if (arguments.length < 2) {
20044       while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
20045       return;
20046     }
20047
20048     // If a type was specified, set the callback for the given type and name.
20049     // Otherwise, if a null callback was specified, remove callbacks of the given name.
20050     if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
20051     while (++i < n) {
20052       if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
20053       else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
20054     }
20055
20056     return this;
20057   },
20058   copy: function() {
20059     var copy = {}, _ = this._;
20060     for (var t in _) copy[t] = _[t].slice();
20061     return new Dispatch(copy);
20062   },
20063   call: function(type, that) {
20064     if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
20065     if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
20066     for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
20067   },
20068   apply: function(type, that, args) {
20069     if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
20070     for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
20071   }
20072 };
20073
20074 function get(type, name) {
20075   for (var i = 0, n = type.length, c; i < n; ++i) {
20076     if ((c = type[i]).name === name) {
20077       return c.value;
20078     }
20079   }
20080 }
20081
20082 function set(type, name, callback) {
20083   for (var i = 0, n = type.length; i < n; ++i) {
20084     if (type[i].name === name) {
20085       type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
20086       break;
20087     }
20088   }
20089   if (callback != null) type.push({name: name, value: callback});
20090   return type;
20091 }
20092
20093 var xhtml = "http://www.w3.org/1999/xhtml";
20094
20095 var namespaces = {
20096   svg: "http://www.w3.org/2000/svg",
20097   xhtml: xhtml,
20098   xlink: "http://www.w3.org/1999/xlink",
20099   xml: "http://www.w3.org/XML/1998/namespace",
20100   xmlns: "http://www.w3.org/2000/xmlns/"
20101 };
20102
20103 var namespace = function(name) {
20104   var prefix = name += "", i = prefix.indexOf(":");
20105   if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
20106   return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
20107 };
20108
20109 function creatorInherit(name) {
20110   return function() {
20111     var document = this.ownerDocument,
20112         uri = this.namespaceURI;
20113     return uri === xhtml && document.documentElement.namespaceURI === xhtml
20114         ? document.createElement(name)
20115         : document.createElementNS(uri, name);
20116   };
20117 }
20118
20119 function creatorFixed(fullname) {
20120   return function() {
20121     return this.ownerDocument.createElementNS(fullname.space, fullname.local);
20122   };
20123 }
20124
20125 var creator = function(name) {
20126   var fullname = namespace(name);
20127   return (fullname.local
20128       ? creatorFixed
20129       : creatorInherit)(fullname);
20130 };
20131
20132 var nextId = 0;
20133
20134 function local$1() {
20135   return new Local;
20136 }
20137
20138 function Local() {
20139   this._ = "@" + (++nextId).toString(36);
20140 }
20141
20142 Local.prototype = local$1.prototype = {
20143   constructor: Local,
20144   get: function(node) {
20145     var id = this._;
20146     while (!(id in node)) if (!(node = node.parentNode)) return;
20147     return node[id];
20148   },
20149   set: function(node, value) {
20150     return node[this._] = value;
20151   },
20152   remove: function(node) {
20153     return this._ in node && delete node[this._];
20154   },
20155   toString: function() {
20156     return this._;
20157   }
20158 };
20159
20160 var matcher = function(selector) {
20161   return function() {
20162     return this.matches(selector);
20163   };
20164 };
20165
20166 if (typeof document !== "undefined") {
20167   var element = document.documentElement;
20168   if (!element.matches) {
20169     var vendorMatches = element.webkitMatchesSelector
20170         || element.msMatchesSelector
20171         || element.mozMatchesSelector
20172         || element.oMatchesSelector;
20173     matcher = function(selector) {
20174       return function() {
20175         return vendorMatches.call(this, selector);
20176       };
20177     };
20178   }
20179 }
20180
20181 var matcher$1 = matcher;
20182
20183 var filterEvents = {};
20184
20185 var event = null;
20186
20187 if (typeof document !== "undefined") {
20188   var element$1 = document.documentElement;
20189   if (!("onmouseenter" in element$1)) {
20190     filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
20191   }
20192 }
20193
20194 function filterContextListener(listener, index, group) {
20195   listener = contextListener(listener, index, group);
20196   return function(event) {
20197     var related = event.relatedTarget;
20198     if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
20199       listener.call(this, event);
20200     }
20201   };
20202 }
20203
20204 function contextListener(listener, index, group) {
20205   return function(event1) {
20206     var event0 = event; // Events can be reentrant (e.g., focus).
20207     event = event1;
20208     try {
20209       listener.call(this, this.__data__, index, group);
20210     } finally {
20211       event = event0;
20212     }
20213   };
20214 }
20215
20216 function parseTypenames$1(typenames) {
20217   return typenames.trim().split(/^|\s+/).map(function(t) {
20218     var name = "", i = t.indexOf(".");
20219     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
20220     return {type: t, name: name};
20221   });
20222 }
20223
20224 function onRemove(typename) {
20225   return function() {
20226     var on = this.__on;
20227     if (!on) return;
20228     for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
20229       if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
20230         this.removeEventListener(o.type, o.listener, o.capture);
20231       } else {
20232         on[++i] = o;
20233       }
20234     }
20235     if (++i) on.length = i;
20236     else delete this.__on;
20237   };
20238 }
20239
20240 function onAdd(typename, value, capture) {
20241   var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
20242   return function(d, i, group) {
20243     var on = this.__on, o, listener = wrap(value, i, group);
20244     if (on) for (var j = 0, m = on.length; j < m; ++j) {
20245       if ((o = on[j]).type === typename.type && o.name === typename.name) {
20246         this.removeEventListener(o.type, o.listener, o.capture);
20247         this.addEventListener(o.type, o.listener = listener, o.capture = capture);
20248         o.value = value;
20249         return;
20250       }
20251     }
20252     this.addEventListener(typename.type, listener, capture);
20253     o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
20254     if (!on) this.__on = [o];
20255     else on.push(o);
20256   };
20257 }
20258
20259 var selection_on = function(typename, value, capture) {
20260   var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
20261
20262   if (arguments.length < 2) {
20263     var on = this.node().__on;
20264     if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
20265       for (i = 0, o = on[j]; i < n; ++i) {
20266         if ((t = typenames[i]).type === o.type && t.name === o.name) {
20267           return o.value;
20268         }
20269       }
20270     }
20271     return;
20272   }
20273
20274   on = value ? onAdd : onRemove;
20275   if (capture == null) capture = false;
20276   for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
20277   return this;
20278 };
20279
20280 function customEvent(event1, listener, that, args) {
20281   var event0 = event;
20282   event1.sourceEvent = event;
20283   event = event1;
20284   try {
20285     return listener.apply(that, args);
20286   } finally {
20287     event = event0;
20288   }
20289 }
20290
20291 var sourceEvent = function() {
20292   var current = event, source;
20293   while (source = current.sourceEvent) current = source;
20294   return current;
20295 };
20296
20297 var point = function(node, event) {
20298   var svg = node.ownerSVGElement || node;
20299
20300   if (svg.createSVGPoint) {
20301     var point = svg.createSVGPoint();
20302     point.x = event.clientX, point.y = event.clientY;
20303     point = point.matrixTransform(node.getScreenCTM().inverse());
20304     return [point.x, point.y];
20305   }
20306
20307   var rect = node.getBoundingClientRect();
20308   return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
20309 };
20310
20311 var mouse = function(node) {
20312   var event = sourceEvent();
20313   if (event.changedTouches) event = event.changedTouches[0];
20314   return point(node, event);
20315 };
20316
20317 function none() {}
20318
20319 var selector = function(selector) {
20320   return selector == null ? none : function() {
20321     return this.querySelector(selector);
20322   };
20323 };
20324
20325 var selection_select = function(select) {
20326   if (typeof select !== "function") select = selector(select);
20327
20328   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
20329     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
20330       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
20331         if ("__data__" in node) subnode.__data__ = node.__data__;
20332         subgroup[i] = subnode;
20333       }
20334     }
20335   }
20336
20337   return new Selection(subgroups, this._parents);
20338 };
20339
20340 function empty$1() {
20341   return [];
20342 }
20343
20344 var selectorAll = function(selector) {
20345   return selector == null ? empty$1 : function() {
20346     return this.querySelectorAll(selector);
20347   };
20348 };
20349
20350 var selection_selectAll = function(select) {
20351   if (typeof select !== "function") select = selectorAll(select);
20352
20353   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
20354     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
20355       if (node = group[i]) {
20356         subgroups.push(select.call(node, node.__data__, i, group));
20357         parents.push(node);
20358       }
20359     }
20360   }
20361
20362   return new Selection(subgroups, parents);
20363 };
20364
20365 var selection_filter = function(match) {
20366   if (typeof match !== "function") match = matcher$1(match);
20367
20368   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
20369     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
20370       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
20371         subgroup.push(node);
20372       }
20373     }
20374   }
20375
20376   return new Selection(subgroups, this._parents);
20377 };
20378
20379 var sparse = function(update) {
20380   return new Array(update.length);
20381 };
20382
20383 var selection_enter = function() {
20384   return new Selection(this._enter || this._groups.map(sparse), this._parents);
20385 };
20386
20387 function EnterNode(parent, datum) {
20388   this.ownerDocument = parent.ownerDocument;
20389   this.namespaceURI = parent.namespaceURI;
20390   this._next = null;
20391   this._parent = parent;
20392   this.__data__ = datum;
20393 }
20394
20395 EnterNode.prototype = {
20396   constructor: EnterNode,
20397   appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
20398   insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
20399   querySelector: function(selector) { return this._parent.querySelector(selector); },
20400   querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
20401 };
20402
20403 var constant$1 = function(x) {
20404   return function() {
20405     return x;
20406   };
20407 };
20408
20409 var keyPrefix = "$"; // Protect against keys like “__proto__”.
20410
20411 function bindIndex(parent, group, enter, update, exit, data) {
20412   var i = 0,
20413       node,
20414       groupLength = group.length,
20415       dataLength = data.length;
20416
20417   // Put any non-null nodes that fit into update.
20418   // Put any null nodes into enter.
20419   // Put any remaining data into enter.
20420   for (; i < dataLength; ++i) {
20421     if (node = group[i]) {
20422       node.__data__ = data[i];
20423       update[i] = node;
20424     } else {
20425       enter[i] = new EnterNode(parent, data[i]);
20426     }
20427   }
20428
20429   // Put any non-null nodes that don’t fit into exit.
20430   for (; i < groupLength; ++i) {
20431     if (node = group[i]) {
20432       exit[i] = node;
20433     }
20434   }
20435 }
20436
20437 function bindKey(parent, group, enter, update, exit, data, key) {
20438   var i,
20439       node,
20440       nodeByKeyValue = {},
20441       groupLength = group.length,
20442       dataLength = data.length,
20443       keyValues = new Array(groupLength),
20444       keyValue;
20445
20446   // Compute the key for each node.
20447   // If multiple nodes have the same key, the duplicates are added to exit.
20448   for (i = 0; i < groupLength; ++i) {
20449     if (node = group[i]) {
20450       keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
20451       if (keyValue in nodeByKeyValue) {
20452         exit[i] = node;
20453       } else {
20454         nodeByKeyValue[keyValue] = node;
20455       }
20456     }
20457   }
20458
20459   // Compute the key for each datum.
20460   // If there a node associated with this key, join and add it to update.
20461   // If there is not (or the key is a duplicate), add it to enter.
20462   for (i = 0; i < dataLength; ++i) {
20463     keyValue = keyPrefix + key.call(parent, data[i], i, data);
20464     if (node = nodeByKeyValue[keyValue]) {
20465       update[i] = node;
20466       node.__data__ = data[i];
20467       nodeByKeyValue[keyValue] = null;
20468     } else {
20469       enter[i] = new EnterNode(parent, data[i]);
20470     }
20471   }
20472
20473   // Add any remaining nodes that were not bound to data to exit.
20474   for (i = 0; i < groupLength; ++i) {
20475     if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
20476       exit[i] = node;
20477     }
20478   }
20479 }
20480
20481 var selection_data = function(value, key) {
20482   if (!value) {
20483     data = new Array(this.size()), j = -1;
20484     this.each(function(d) { data[++j] = d; });
20485     return data;
20486   }
20487
20488   var bind = key ? bindKey : bindIndex,
20489       parents = this._parents,
20490       groups = this._groups;
20491
20492   if (typeof value !== "function") value = constant$1(value);
20493
20494   for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
20495     var parent = parents[j],
20496         group = groups[j],
20497         groupLength = group.length,
20498         data = value.call(parent, parent && parent.__data__, j, parents),
20499         dataLength = data.length,
20500         enterGroup = enter[j] = new Array(dataLength),
20501         updateGroup = update[j] = new Array(dataLength),
20502         exitGroup = exit[j] = new Array(groupLength);
20503
20504     bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
20505
20506     // Now connect the enter nodes to their following update node, such that
20507     // appendChild can insert the materialized enter node before this node,
20508     // rather than at the end of the parent node.
20509     for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
20510       if (previous = enterGroup[i0]) {
20511         if (i0 >= i1) i1 = i0 + 1;
20512         while (!(next = updateGroup[i1]) && ++i1 < dataLength);
20513         previous._next = next || null;
20514       }
20515     }
20516   }
20517
20518   update = new Selection(update, parents);
20519   update._enter = enter;
20520   update._exit = exit;
20521   return update;
20522 };
20523
20524 var selection_exit = function() {
20525   return new Selection(this._exit || this._groups.map(sparse), this._parents);
20526 };
20527
20528 var selection_merge = function(selection$$1) {
20529
20530   for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
20531     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
20532       if (node = group0[i] || group1[i]) {
20533         merge[i] = node;
20534       }
20535     }
20536   }
20537
20538   for (; j < m0; ++j) {
20539     merges[j] = groups0[j];
20540   }
20541
20542   return new Selection(merges, this._parents);
20543 };
20544
20545 var selection_order = function() {
20546
20547   for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
20548     for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
20549       if (node = group[i]) {
20550         if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
20551         next = node;
20552       }
20553     }
20554   }
20555
20556   return this;
20557 };
20558
20559 var selection_sort = function(compare) {
20560   if (!compare) compare = ascending$1;
20561
20562   function compareNode(a, b) {
20563     return a && b ? compare(a.__data__, b.__data__) : !a - !b;
20564   }
20565
20566   for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
20567     for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
20568       if (node = group[i]) {
20569         sortgroup[i] = node;
20570       }
20571     }
20572     sortgroup.sort(compareNode);
20573   }
20574
20575   return new Selection(sortgroups, this._parents).order();
20576 };
20577
20578 function ascending$1(a, b) {
20579   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
20580 }
20581
20582 var selection_call = function() {
20583   var callback = arguments[0];
20584   arguments[0] = this;
20585   callback.apply(null, arguments);
20586   return this;
20587 };
20588
20589 var selection_nodes = function() {
20590   var nodes = new Array(this.size()), i = -1;
20591   this.each(function() { nodes[++i] = this; });
20592   return nodes;
20593 };
20594
20595 var selection_node = function() {
20596
20597   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
20598     for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
20599       var node = group[i];
20600       if (node) return node;
20601     }
20602   }
20603
20604   return null;
20605 };
20606
20607 var selection_size = function() {
20608   var size = 0;
20609   this.each(function() { ++size; });
20610   return size;
20611 };
20612
20613 var selection_empty = function() {
20614   return !this.node();
20615 };
20616
20617 var selection_each = function(callback) {
20618
20619   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
20620     for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
20621       if (node = group[i]) callback.call(node, node.__data__, i, group);
20622     }
20623   }
20624
20625   return this;
20626 };
20627
20628 function attrRemove(name) {
20629   return function() {
20630     this.removeAttribute(name);
20631   };
20632 }
20633
20634 function attrRemoveNS(fullname) {
20635   return function() {
20636     this.removeAttributeNS(fullname.space, fullname.local);
20637   };
20638 }
20639
20640 function attrConstant(name, value) {
20641   return function() {
20642     this.setAttribute(name, value);
20643   };
20644 }
20645
20646 function attrConstantNS(fullname, value) {
20647   return function() {
20648     this.setAttributeNS(fullname.space, fullname.local, value);
20649   };
20650 }
20651
20652 function attrFunction(name, value) {
20653   return function() {
20654     var v = value.apply(this, arguments);
20655     if (v == null) this.removeAttribute(name);
20656     else this.setAttribute(name, v);
20657   };
20658 }
20659
20660 function attrFunctionNS(fullname, value) {
20661   return function() {
20662     var v = value.apply(this, arguments);
20663     if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
20664     else this.setAttributeNS(fullname.space, fullname.local, v);
20665   };
20666 }
20667
20668 var selection_attr = function(name, value) {
20669   var fullname = namespace(name);
20670
20671   if (arguments.length < 2) {
20672     var node = this.node();
20673     return fullname.local
20674         ? node.getAttributeNS(fullname.space, fullname.local)
20675         : node.getAttribute(fullname);
20676   }
20677
20678   return this.each((value == null
20679       ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
20680       ? (fullname.local ? attrFunctionNS : attrFunction)
20681       : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
20682 };
20683
20684 var defaultView = function(node) {
20685   return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
20686       || (node.document && node) // node is a Window
20687       || node.defaultView; // node is a Document
20688 };
20689
20690 function styleRemove(name) {
20691   return function() {
20692     this.style.removeProperty(name);
20693   };
20694 }
20695
20696 function styleConstant(name, value, priority) {
20697   return function() {
20698     this.style.setProperty(name, value, priority);
20699   };
20700 }
20701
20702 function styleFunction(name, value, priority) {
20703   return function() {
20704     var v = value.apply(this, arguments);
20705     if (v == null) this.style.removeProperty(name);
20706     else this.style.setProperty(name, v, priority);
20707   };
20708 }
20709
20710 var selection_style = function(name, value, priority) {
20711   return arguments.length > 1
20712       ? this.each((value == null
20713             ? styleRemove : typeof value === "function"
20714             ? styleFunction
20715             : styleConstant)(name, value, priority == null ? "" : priority))
20716       : styleValue(this.node(), name);
20717 };
20718
20719 function styleValue(node, name) {
20720   return node.style.getPropertyValue(name)
20721       || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
20722 }
20723
20724 function propertyRemove(name) {
20725   return function() {
20726     delete this[name];
20727   };
20728 }
20729
20730 function propertyConstant(name, value) {
20731   return function() {
20732     this[name] = value;
20733   };
20734 }
20735
20736 function propertyFunction(name, value) {
20737   return function() {
20738     var v = value.apply(this, arguments);
20739     if (v == null) delete this[name];
20740     else this[name] = v;
20741   };
20742 }
20743
20744 var selection_property = function(name, value) {
20745   return arguments.length > 1
20746       ? this.each((value == null
20747           ? propertyRemove : typeof value === "function"
20748           ? propertyFunction
20749           : propertyConstant)(name, value))
20750       : this.node()[name];
20751 };
20752
20753 function classArray(string) {
20754   return string.trim().split(/^|\s+/);
20755 }
20756
20757 function classList(node) {
20758   return node.classList || new ClassList(node);
20759 }
20760
20761 function ClassList(node) {
20762   this._node = node;
20763   this._names = classArray(node.getAttribute("class") || "");
20764 }
20765
20766 ClassList.prototype = {
20767   add: function(name) {
20768     var i = this._names.indexOf(name);
20769     if (i < 0) {
20770       this._names.push(name);
20771       this._node.setAttribute("class", this._names.join(" "));
20772     }
20773   },
20774   remove: function(name) {
20775     var i = this._names.indexOf(name);
20776     if (i >= 0) {
20777       this._names.splice(i, 1);
20778       this._node.setAttribute("class", this._names.join(" "));
20779     }
20780   },
20781   contains: function(name) {
20782     return this._names.indexOf(name) >= 0;
20783   }
20784 };
20785
20786 function classedAdd(node, names) {
20787   var list = classList(node), i = -1, n = names.length;
20788   while (++i < n) list.add(names[i]);
20789 }
20790
20791 function classedRemove(node, names) {
20792   var list = classList(node), i = -1, n = names.length;
20793   while (++i < n) list.remove(names[i]);
20794 }
20795
20796 function classedTrue(names) {
20797   return function() {
20798     classedAdd(this, names);
20799   };
20800 }
20801
20802 function classedFalse(names) {
20803   return function() {
20804     classedRemove(this, names);
20805   };
20806 }
20807
20808 function classedFunction(names, value) {
20809   return function() {
20810     (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
20811   };
20812 }
20813
20814 var selection_classed = function(name, value) {
20815   var names = classArray(name + "");
20816
20817   if (arguments.length < 2) {
20818     var list = classList(this.node()), i = -1, n = names.length;
20819     while (++i < n) if (!list.contains(names[i])) return false;
20820     return true;
20821   }
20822
20823   return this.each((typeof value === "function"
20824       ? classedFunction : value
20825       ? classedTrue
20826       : classedFalse)(names, value));
20827 };
20828
20829 function textRemove() {
20830   this.textContent = "";
20831 }
20832
20833 function textConstant(value) {
20834   return function() {
20835     this.textContent = value;
20836   };
20837 }
20838
20839 function textFunction(value) {
20840   return function() {
20841     var v = value.apply(this, arguments);
20842     this.textContent = v == null ? "" : v;
20843   };
20844 }
20845
20846 var selection_text = function(value) {
20847   return arguments.length
20848       ? this.each(value == null
20849           ? textRemove : (typeof value === "function"
20850           ? textFunction
20851           : textConstant)(value))
20852       : this.node().textContent;
20853 };
20854
20855 function htmlRemove() {
20856   this.innerHTML = "";
20857 }
20858
20859 function htmlConstant(value) {
20860   return function() {
20861     this.innerHTML = value;
20862   };
20863 }
20864
20865 function htmlFunction(value) {
20866   return function() {
20867     var v = value.apply(this, arguments);
20868     this.innerHTML = v == null ? "" : v;
20869   };
20870 }
20871
20872 var selection_html = function(value) {
20873   return arguments.length
20874       ? this.each(value == null
20875           ? htmlRemove : (typeof value === "function"
20876           ? htmlFunction
20877           : htmlConstant)(value))
20878       : this.node().innerHTML;
20879 };
20880
20881 function raise() {
20882   if (this.nextSibling) this.parentNode.appendChild(this);
20883 }
20884
20885 var selection_raise = function() {
20886   return this.each(raise);
20887 };
20888
20889 function lower() {
20890   if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
20891 }
20892
20893 var selection_lower = function() {
20894   return this.each(lower);
20895 };
20896
20897 var selection_append = function(name) {
20898   var create = typeof name === "function" ? name : creator(name);
20899   return this.select(function() {
20900     return this.appendChild(create.apply(this, arguments));
20901   });
20902 };
20903
20904 function constantNull() {
20905   return null;
20906 }
20907
20908 var selection_insert = function(name, before) {
20909   var create = typeof name === "function" ? name : creator(name),
20910       select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
20911   return this.select(function() {
20912     return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
20913   });
20914 };
20915
20916 function remove() {
20917   var parent = this.parentNode;
20918   if (parent) parent.removeChild(this);
20919 }
20920
20921 var selection_remove = function() {
20922   return this.each(remove);
20923 };
20924
20925 var selection_datum = function(value) {
20926   return arguments.length
20927       ? this.property("__data__", value)
20928       : this.node().__data__;
20929 };
20930
20931 function dispatchEvent(node, type, params) {
20932   var window = defaultView(node),
20933       event = window.CustomEvent;
20934
20935   if (typeof event === "function") {
20936     event = new event(type, params);
20937   } else {
20938     event = window.document.createEvent("Event");
20939     if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
20940     else event.initEvent(type, false, false);
20941   }
20942
20943   node.dispatchEvent(event);
20944 }
20945
20946 function dispatchConstant(type, params) {
20947   return function() {
20948     return dispatchEvent(this, type, params);
20949   };
20950 }
20951
20952 function dispatchFunction(type, params) {
20953   return function() {
20954     return dispatchEvent(this, type, params.apply(this, arguments));
20955   };
20956 }
20957
20958 var selection_dispatch = function(type, params) {
20959   return this.each((typeof params === "function"
20960       ? dispatchFunction
20961       : dispatchConstant)(type, params));
20962 };
20963
20964 var root = [null];
20965
20966 function Selection(groups, parents) {
20967   this._groups = groups;
20968   this._parents = parents;
20969 }
20970
20971 function selection() {
20972   return new Selection([[document.documentElement]], root);
20973 }
20974
20975 Selection.prototype = selection.prototype = {
20976   constructor: Selection,
20977   select: selection_select,
20978   selectAll: selection_selectAll,
20979   filter: selection_filter,
20980   data: selection_data,
20981   enter: selection_enter,
20982   exit: selection_exit,
20983   merge: selection_merge,
20984   order: selection_order,
20985   sort: selection_sort,
20986   call: selection_call,
20987   nodes: selection_nodes,
20988   node: selection_node,
20989   size: selection_size,
20990   empty: selection_empty,
20991   each: selection_each,
20992   attr: selection_attr,
20993   style: selection_style,
20994   property: selection_property,
20995   classed: selection_classed,
20996   text: selection_text,
20997   html: selection_html,
20998   raise: selection_raise,
20999   lower: selection_lower,
21000   append: selection_append,
21001   insert: selection_insert,
21002   remove: selection_remove,
21003   datum: selection_datum,
21004   on: selection_on,
21005   dispatch: selection_dispatch
21006 };
21007
21008 var select = function(selector) {
21009   return typeof selector === "string"
21010       ? new Selection([[document.querySelector(selector)]], [document.documentElement])
21011       : new Selection([[selector]], root);
21012 };
21013
21014 var selectAll = function(selector) {
21015   return typeof selector === "string"
21016       ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
21017       : new Selection([selector == null ? [] : selector], root);
21018 };
21019
21020 var touch = function(node, touches, identifier) {
21021   if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
21022
21023   for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
21024     if ((touch = touches[i]).identifier === identifier) {
21025       return point(node, touch);
21026     }
21027   }
21028
21029   return null;
21030 };
21031
21032 var touches = function(node, touches) {
21033   if (touches == null) touches = sourceEvent().touches;
21034
21035   for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
21036     points[i] = point(node, touches[i]);
21037   }
21038
21039   return points;
21040 };
21041
21042 function nopropagation() {
21043   event.stopImmediatePropagation();
21044 }
21045
21046 var noevent = function() {
21047   event.preventDefault();
21048   event.stopImmediatePropagation();
21049 };
21050
21051 var dragDisable = function(view) {
21052   var root = view.document.documentElement,
21053       selection$$1 = select(view).on("dragstart.drag", noevent, true);
21054   if ("onselectstart" in root) {
21055     selection$$1.on("selectstart.drag", noevent, true);
21056   } else {
21057     root.__noselect = root.style.MozUserSelect;
21058     root.style.MozUserSelect = "none";
21059   }
21060 };
21061
21062 function yesdrag(view, noclick) {
21063   var root = view.document.documentElement,
21064       selection$$1 = select(view).on("dragstart.drag", null);
21065   if (noclick) {
21066     selection$$1.on("click.drag", noevent, true);
21067     setTimeout(function() { selection$$1.on("click.drag", null); }, 0);
21068   }
21069   if ("onselectstart" in root) {
21070     selection$$1.on("selectstart.drag", null);
21071   } else {
21072     root.style.MozUserSelect = root.__noselect;
21073     delete root.__noselect;
21074   }
21075 }
21076
21077 var constant$2 = function(x) {
21078   return function() {
21079     return x;
21080   };
21081 };
21082
21083 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
21084   this.target = target;
21085   this.type = type;
21086   this.subject = subject;
21087   this.identifier = id;
21088   this.active = active;
21089   this.x = x;
21090   this.y = y;
21091   this.dx = dx;
21092   this.dy = dy;
21093   this._ = dispatch;
21094 }
21095
21096 DragEvent.prototype.on = function() {
21097   var value = this._.on.apply(this._, arguments);
21098   return value === this._ ? this : value;
21099 };
21100
21101 // Ignore right-click, since that should open the context menu.
21102 function defaultFilter$1() {
21103   return !event.button;
21104 }
21105
21106 function defaultContainer() {
21107   return this.parentNode;
21108 }
21109
21110 function defaultSubject(d) {
21111   return d == null ? {x: event.x, y: event.y} : d;
21112 }
21113
21114 function touchable() {
21115   return "ontouchstart" in this;
21116 }
21117
21118 var drag = function() {
21119   var filter = defaultFilter$1,
21120       container = defaultContainer,
21121       subject = defaultSubject,
21122       gestures = {},
21123       listeners = dispatch("start", "drag", "end"),
21124       active = 0,
21125       mousedownx,
21126       mousedowny,
21127       mousemoving,
21128       touchending,
21129       clickDistance2 = 0;
21130
21131   function drag(selection) {
21132     selection
21133         .on("mousedown.drag", mousedowned)
21134       .filter(touchable)
21135         .on("touchstart.drag", touchstarted)
21136         .on("touchmove.drag", touchmoved)
21137         .on("touchend.drag touchcancel.drag", touchended)
21138         .style("touch-action", "none")
21139         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
21140   }
21141
21142   function mousedowned() {
21143     if (touchending || !filter.apply(this, arguments)) return;
21144     var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments);
21145     if (!gesture) return;
21146     select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
21147     dragDisable(event.view);
21148     nopropagation();
21149     mousemoving = false;
21150     mousedownx = event.clientX;
21151     mousedowny = event.clientY;
21152     gesture("start");
21153   }
21154
21155   function mousemoved() {
21156     noevent();
21157     if (!mousemoving) {
21158       var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
21159       mousemoving = dx * dx + dy * dy > clickDistance2;
21160     }
21161     gestures.mouse("drag");
21162   }
21163
21164   function mouseupped() {
21165     select(event.view).on("mousemove.drag mouseup.drag", null);
21166     yesdrag(event.view, mousemoving);
21167     noevent();
21168     gestures.mouse("end");
21169   }
21170
21171   function touchstarted() {
21172     if (!filter.apply(this, arguments)) return;
21173     var touches$$1 = event.changedTouches,
21174         c = container.apply(this, arguments),
21175         n = touches$$1.length, i, gesture;
21176
21177     for (i = 0; i < n; ++i) {
21178       if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) {
21179         nopropagation();
21180         gesture("start");
21181       }
21182     }
21183   }
21184
21185   function touchmoved() {
21186     var touches$$1 = event.changedTouches,
21187         n = touches$$1.length, i, gesture;
21188
21189     for (i = 0; i < n; ++i) {
21190       if (gesture = gestures[touches$$1[i].identifier]) {
21191         noevent();
21192         gesture("drag");
21193       }
21194     }
21195   }
21196
21197   function touchended() {
21198     var touches$$1 = event.changedTouches,
21199         n = touches$$1.length, i, gesture;
21200
21201     if (touchending) clearTimeout(touchending);
21202     touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
21203     for (i = 0; i < n; ++i) {
21204       if (gesture = gestures[touches$$1[i].identifier]) {
21205         nopropagation();
21206         gesture("end");
21207       }
21208     }
21209   }
21210
21211   function beforestart(id, container, point, that, args) {
21212     var p = point(container, id), s, dx, dy,
21213         sublisteners = listeners.copy();
21214
21215     if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
21216       if ((event.subject = s = subject.apply(that, args)) == null) return false;
21217       dx = s.x - p[0] || 0;
21218       dy = s.y - p[1] || 0;
21219       return true;
21220     })) return;
21221
21222     return function gesture(type) {
21223       var p0 = p, n;
21224       switch (type) {
21225         case "start": gestures[id] = gesture, n = active++; break;
21226         case "end": delete gestures[id], --active; // nobreak
21227         case "drag": p = point(container, id), n = active; break;
21228       }
21229       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]);
21230     };
21231   }
21232
21233   drag.filter = function(_) {
21234     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter;
21235   };
21236
21237   drag.container = function(_) {
21238     return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container;
21239   };
21240
21241   drag.subject = function(_) {
21242     return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject;
21243   };
21244
21245   drag.on = function() {
21246     var value = listeners.on.apply(listeners, arguments);
21247     return value === listeners ? drag : value;
21248   };
21249
21250   drag.clickDistance = function(_) {
21251     return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
21252   };
21253
21254   return drag;
21255 };
21256
21257 var define = function(constructor, factory, prototype) {
21258   constructor.prototype = factory.prototype = prototype;
21259   prototype.constructor = constructor;
21260 };
21261
21262 function extend(parent, definition) {
21263   var prototype = Object.create(parent.prototype);
21264   for (var key in definition) prototype[key] = definition[key];
21265   return prototype;
21266 }
21267
21268 function Color() {}
21269
21270 var darker = 0.7;
21271 var brighter = 1 / darker;
21272
21273 var reI = "\\s*([+-]?\\d+)\\s*";
21274 var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
21275 var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
21276 var reHex3 = /^#([0-9a-f]{3})$/;
21277 var reHex6 = /^#([0-9a-f]{6})$/;
21278 var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
21279 var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
21280 var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
21281 var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
21282 var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
21283 var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
21284
21285 var named = {
21286   aliceblue: 0xf0f8ff,
21287   antiquewhite: 0xfaebd7,
21288   aqua: 0x00ffff,
21289   aquamarine: 0x7fffd4,
21290   azure: 0xf0ffff,
21291   beige: 0xf5f5dc,
21292   bisque: 0xffe4c4,
21293   black: 0x000000,
21294   blanchedalmond: 0xffebcd,
21295   blue: 0x0000ff,
21296   blueviolet: 0x8a2be2,
21297   brown: 0xa52a2a,
21298   burlywood: 0xdeb887,
21299   cadetblue: 0x5f9ea0,
21300   chartreuse: 0x7fff00,
21301   chocolate: 0xd2691e,
21302   coral: 0xff7f50,
21303   cornflowerblue: 0x6495ed,
21304   cornsilk: 0xfff8dc,
21305   crimson: 0xdc143c,
21306   cyan: 0x00ffff,
21307   darkblue: 0x00008b,
21308   darkcyan: 0x008b8b,
21309   darkgoldenrod: 0xb8860b,
21310   darkgray: 0xa9a9a9,
21311   darkgreen: 0x006400,
21312   darkgrey: 0xa9a9a9,
21313   darkkhaki: 0xbdb76b,
21314   darkmagenta: 0x8b008b,
21315   darkolivegreen: 0x556b2f,
21316   darkorange: 0xff8c00,
21317   darkorchid: 0x9932cc,
21318   darkred: 0x8b0000,
21319   darksalmon: 0xe9967a,
21320   darkseagreen: 0x8fbc8f,
21321   darkslateblue: 0x483d8b,
21322   darkslategray: 0x2f4f4f,
21323   darkslategrey: 0x2f4f4f,
21324   darkturquoise: 0x00ced1,
21325   darkviolet: 0x9400d3,
21326   deeppink: 0xff1493,
21327   deepskyblue: 0x00bfff,
21328   dimgray: 0x696969,
21329   dimgrey: 0x696969,
21330   dodgerblue: 0x1e90ff,
21331   firebrick: 0xb22222,
21332   floralwhite: 0xfffaf0,
21333   forestgreen: 0x228b22,
21334   fuchsia: 0xff00ff,
21335   gainsboro: 0xdcdcdc,
21336   ghostwhite: 0xf8f8ff,
21337   gold: 0xffd700,
21338   goldenrod: 0xdaa520,
21339   gray: 0x808080,
21340   green: 0x008000,
21341   greenyellow: 0xadff2f,
21342   grey: 0x808080,
21343   honeydew: 0xf0fff0,
21344   hotpink: 0xff69b4,
21345   indianred: 0xcd5c5c,
21346   indigo: 0x4b0082,
21347   ivory: 0xfffff0,
21348   khaki: 0xf0e68c,
21349   lavender: 0xe6e6fa,
21350   lavenderblush: 0xfff0f5,
21351   lawngreen: 0x7cfc00,
21352   lemonchiffon: 0xfffacd,
21353   lightblue: 0xadd8e6,
21354   lightcoral: 0xf08080,
21355   lightcyan: 0xe0ffff,
21356   lightgoldenrodyellow: 0xfafad2,
21357   lightgray: 0xd3d3d3,
21358   lightgreen: 0x90ee90,
21359   lightgrey: 0xd3d3d3,
21360   lightpink: 0xffb6c1,
21361   lightsalmon: 0xffa07a,
21362   lightseagreen: 0x20b2aa,
21363   lightskyblue: 0x87cefa,
21364   lightslategray: 0x778899,
21365   lightslategrey: 0x778899,
21366   lightsteelblue: 0xb0c4de,
21367   lightyellow: 0xffffe0,
21368   lime: 0x00ff00,
21369   limegreen: 0x32cd32,
21370   linen: 0xfaf0e6,
21371   magenta: 0xff00ff,
21372   maroon: 0x800000,
21373   mediumaquamarine: 0x66cdaa,
21374   mediumblue: 0x0000cd,
21375   mediumorchid: 0xba55d3,
21376   mediumpurple: 0x9370db,
21377   mediumseagreen: 0x3cb371,
21378   mediumslateblue: 0x7b68ee,
21379   mediumspringgreen: 0x00fa9a,
21380   mediumturquoise: 0x48d1cc,
21381   mediumvioletred: 0xc71585,
21382   midnightblue: 0x191970,
21383   mintcream: 0xf5fffa,
21384   mistyrose: 0xffe4e1,
21385   moccasin: 0xffe4b5,
21386   navajowhite: 0xffdead,
21387   navy: 0x000080,
21388   oldlace: 0xfdf5e6,
21389   olive: 0x808000,
21390   olivedrab: 0x6b8e23,
21391   orange: 0xffa500,
21392   orangered: 0xff4500,
21393   orchid: 0xda70d6,
21394   palegoldenrod: 0xeee8aa,
21395   palegreen: 0x98fb98,
21396   paleturquoise: 0xafeeee,
21397   palevioletred: 0xdb7093,
21398   papayawhip: 0xffefd5,
21399   peachpuff: 0xffdab9,
21400   peru: 0xcd853f,
21401   pink: 0xffc0cb,
21402   plum: 0xdda0dd,
21403   powderblue: 0xb0e0e6,
21404   purple: 0x800080,
21405   rebeccapurple: 0x663399,
21406   red: 0xff0000,
21407   rosybrown: 0xbc8f8f,
21408   royalblue: 0x4169e1,
21409   saddlebrown: 0x8b4513,
21410   salmon: 0xfa8072,
21411   sandybrown: 0xf4a460,
21412   seagreen: 0x2e8b57,
21413   seashell: 0xfff5ee,
21414   sienna: 0xa0522d,
21415   silver: 0xc0c0c0,
21416   skyblue: 0x87ceeb,
21417   slateblue: 0x6a5acd,
21418   slategray: 0x708090,
21419   slategrey: 0x708090,
21420   snow: 0xfffafa,
21421   springgreen: 0x00ff7f,
21422   steelblue: 0x4682b4,
21423   tan: 0xd2b48c,
21424   teal: 0x008080,
21425   thistle: 0xd8bfd8,
21426   tomato: 0xff6347,
21427   turquoise: 0x40e0d0,
21428   violet: 0xee82ee,
21429   wheat: 0xf5deb3,
21430   white: 0xffffff,
21431   whitesmoke: 0xf5f5f5,
21432   yellow: 0xffff00,
21433   yellowgreen: 0x9acd32
21434 };
21435
21436 define(Color, color, {
21437   displayable: function() {
21438     return this.rgb().displayable();
21439   },
21440   toString: function() {
21441     return this.rgb() + "";
21442   }
21443 });
21444
21445 function color(format) {
21446   var m;
21447   format = (format + "").trim().toLowerCase();
21448   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
21449       : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
21450       : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
21451       : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
21452       : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
21453       : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
21454       : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
21455       : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
21456       : named.hasOwnProperty(format) ? rgbn(named[format])
21457       : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
21458       : null;
21459 }
21460
21461 function rgbn(n) {
21462   return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
21463 }
21464
21465 function rgba(r, g, b, a) {
21466   if (a <= 0) r = g = b = NaN;
21467   return new Rgb(r, g, b, a);
21468 }
21469
21470 function rgbConvert(o) {
21471   if (!(o instanceof Color)) o = color(o);
21472   if (!o) return new Rgb;
21473   o = o.rgb();
21474   return new Rgb(o.r, o.g, o.b, o.opacity);
21475 }
21476
21477 function rgb(r, g, b, opacity) {
21478   return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
21479 }
21480
21481 function Rgb(r, g, b, opacity) {
21482   this.r = +r;
21483   this.g = +g;
21484   this.b = +b;
21485   this.opacity = +opacity;
21486 }
21487
21488 define(Rgb, rgb, extend(Color, {
21489   brighter: function(k) {
21490     k = k == null ? brighter : Math.pow(brighter, k);
21491     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
21492   },
21493   darker: function(k) {
21494     k = k == null ? darker : Math.pow(darker, k);
21495     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
21496   },
21497   rgb: function() {
21498     return this;
21499   },
21500   displayable: function() {
21501     return (0 <= this.r && this.r <= 255)
21502         && (0 <= this.g && this.g <= 255)
21503         && (0 <= this.b && this.b <= 255)
21504         && (0 <= this.opacity && this.opacity <= 1);
21505   },
21506   toString: function() {
21507     var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
21508     return (a === 1 ? "rgb(" : "rgba(")
21509         + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
21510         + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
21511         + Math.max(0, Math.min(255, Math.round(this.b) || 0))
21512         + (a === 1 ? ")" : ", " + a + ")");
21513   }
21514 }));
21515
21516 function hsla(h, s, l, a) {
21517   if (a <= 0) h = s = l = NaN;
21518   else if (l <= 0 || l >= 1) h = s = NaN;
21519   else if (s <= 0) h = NaN;
21520   return new Hsl(h, s, l, a);
21521 }
21522
21523 function hslConvert(o) {
21524   if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
21525   if (!(o instanceof Color)) o = color(o);
21526   if (!o) return new Hsl;
21527   if (o instanceof Hsl) return o;
21528   o = o.rgb();
21529   var r = o.r / 255,
21530       g = o.g / 255,
21531       b = o.b / 255,
21532       min = Math.min(r, g, b),
21533       max = Math.max(r, g, b),
21534       h = NaN,
21535       s = max - min,
21536       l = (max + min) / 2;
21537   if (s) {
21538     if (r === max) h = (g - b) / s + (g < b) * 6;
21539     else if (g === max) h = (b - r) / s + 2;
21540     else h = (r - g) / s + 4;
21541     s /= l < 0.5 ? max + min : 2 - max - min;
21542     h *= 60;
21543   } else {
21544     s = l > 0 && l < 1 ? 0 : h;
21545   }
21546   return new Hsl(h, s, l, o.opacity);
21547 }
21548
21549 function hsl(h, s, l, opacity) {
21550   return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
21551 }
21552
21553 function Hsl(h, s, l, opacity) {
21554   this.h = +h;
21555   this.s = +s;
21556   this.l = +l;
21557   this.opacity = +opacity;
21558 }
21559
21560 define(Hsl, hsl, extend(Color, {
21561   brighter: function(k) {
21562     k = k == null ? brighter : Math.pow(brighter, k);
21563     return new Hsl(this.h, this.s, this.l * k, this.opacity);
21564   },
21565   darker: function(k) {
21566     k = k == null ? darker : Math.pow(darker, k);
21567     return new Hsl(this.h, this.s, this.l * k, this.opacity);
21568   },
21569   rgb: function() {
21570     var h = this.h % 360 + (this.h < 0) * 360,
21571         s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
21572         l = this.l,
21573         m2 = l + (l < 0.5 ? l : 1 - l) * s,
21574         m1 = 2 * l - m2;
21575     return new Rgb(
21576       hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
21577       hsl2rgb(h, m1, m2),
21578       hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
21579       this.opacity
21580     );
21581   },
21582   displayable: function() {
21583     return (0 <= this.s && this.s <= 1 || isNaN(this.s))
21584         && (0 <= this.l && this.l <= 1)
21585         && (0 <= this.opacity && this.opacity <= 1);
21586   }
21587 }));
21588
21589 /* From FvD 13.37, CSS Color Module Level 3 */
21590 function hsl2rgb(h, m1, m2) {
21591   return (h < 60 ? m1 + (m2 - m1) * h / 60
21592       : h < 180 ? m2
21593       : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
21594       : m1) * 255;
21595 }
21596
21597 var deg2rad = Math.PI / 180;
21598 var rad2deg = 180 / Math.PI;
21599
21600 var Kn = 18;
21601 var Xn = 0.950470;
21602 var Yn = 1;
21603 var Zn = 1.088830;
21604 var t0 = 4 / 29;
21605 var t1 = 6 / 29;
21606 var t2 = 3 * t1 * t1;
21607 var t3 = t1 * t1 * t1;
21608
21609 function labConvert(o) {
21610   if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
21611   if (o instanceof Hcl) {
21612     var h = o.h * deg2rad;
21613     return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
21614   }
21615   if (!(o instanceof Rgb)) o = rgbConvert(o);
21616   var b = rgb2xyz(o.r),
21617       a = rgb2xyz(o.g),
21618       l = rgb2xyz(o.b),
21619       x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
21620       y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
21621       z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
21622   return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
21623 }
21624
21625 function lab(l, a, b, opacity) {
21626   return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
21627 }
21628
21629 function Lab(l, a, b, opacity) {
21630   this.l = +l;
21631   this.a = +a;
21632   this.b = +b;
21633   this.opacity = +opacity;
21634 }
21635
21636 define(Lab, lab, extend(Color, {
21637   brighter: function(k) {
21638     return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
21639   },
21640   darker: function(k) {
21641     return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
21642   },
21643   rgb: function() {
21644     var y = (this.l + 16) / 116,
21645         x = isNaN(this.a) ? y : y + this.a / 500,
21646         z = isNaN(this.b) ? y : y - this.b / 200;
21647     y = Yn * lab2xyz(y);
21648     x = Xn * lab2xyz(x);
21649     z = Zn * lab2xyz(z);
21650     return new Rgb(
21651       xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
21652       xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
21653       xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
21654       this.opacity
21655     );
21656   }
21657 }));
21658
21659 function xyz2lab(t) {
21660   return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
21661 }
21662
21663 function lab2xyz(t) {
21664   return t > t1 ? t * t * t : t2 * (t - t0);
21665 }
21666
21667 function xyz2rgb(x) {
21668   return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
21669 }
21670
21671 function rgb2xyz(x) {
21672   return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
21673 }
21674
21675 function hclConvert(o) {
21676   if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
21677   if (!(o instanceof Lab)) o = labConvert(o);
21678   var h = Math.atan2(o.b, o.a) * rad2deg;
21679   return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
21680 }
21681
21682 function hcl(h, c, l, opacity) {
21683   return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
21684 }
21685
21686 function Hcl(h, c, l, opacity) {
21687   this.h = +h;
21688   this.c = +c;
21689   this.l = +l;
21690   this.opacity = +opacity;
21691 }
21692
21693 define(Hcl, hcl, extend(Color, {
21694   brighter: function(k) {
21695     return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
21696   },
21697   darker: function(k) {
21698     return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
21699   },
21700   rgb: function() {
21701     return labConvert(this).rgb();
21702   }
21703 }));
21704
21705 var A = -0.14861;
21706 var B = +1.78277;
21707 var C = -0.29227;
21708 var D = -0.90649;
21709 var E = +1.97294;
21710 var ED = E * D;
21711 var EB = E * B;
21712 var BC_DA = B * C - D * A;
21713
21714 function cubehelixConvert(o) {
21715   if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
21716   if (!(o instanceof Rgb)) o = rgbConvert(o);
21717   var r = o.r / 255,
21718       g = o.g / 255,
21719       b = o.b / 255,
21720       l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
21721       bl = b - l,
21722       k = (E * (g - l) - C * bl) / D,
21723       s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
21724       h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
21725   return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
21726 }
21727
21728 function cubehelix(h, s, l, opacity) {
21729   return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
21730 }
21731
21732 function Cubehelix(h, s, l, opacity) {
21733   this.h = +h;
21734   this.s = +s;
21735   this.l = +l;
21736   this.opacity = +opacity;
21737 }
21738
21739 define(Cubehelix, cubehelix, extend(Color, {
21740   brighter: function(k) {
21741     k = k == null ? brighter : Math.pow(brighter, k);
21742     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
21743   },
21744   darker: function(k) {
21745     k = k == null ? darker : Math.pow(darker, k);
21746     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
21747   },
21748   rgb: function() {
21749     var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
21750         l = +this.l,
21751         a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
21752         cosh = Math.cos(h),
21753         sinh = Math.sin(h);
21754     return new Rgb(
21755       255 * (l + a * (A * cosh + B * sinh)),
21756       255 * (l + a * (C * cosh + D * sinh)),
21757       255 * (l + a * (E * cosh)),
21758       this.opacity
21759     );
21760   }
21761 }));
21762
21763 function basis(t1, v0, v1, v2, v3) {
21764   var t2 = t1 * t1, t3 = t2 * t1;
21765   return ((1 - 3 * t1 + 3 * t2 - t3) * v0
21766       + (4 - 6 * t2 + 3 * t3) * v1
21767       + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
21768       + t3 * v3) / 6;
21769 }
21770
21771 var basis$1 = function(values) {
21772   var n = values.length - 1;
21773   return function(t) {
21774     var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
21775         v1 = values[i],
21776         v2 = values[i + 1],
21777         v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
21778         v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
21779     return basis((t - i / n) * n, v0, v1, v2, v3);
21780   };
21781 };
21782
21783 var basisClosed = function(values) {
21784   var n = values.length;
21785   return function(t) {
21786     var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
21787         v0 = values[(i + n - 1) % n],
21788         v1 = values[i % n],
21789         v2 = values[(i + 1) % n],
21790         v3 = values[(i + 2) % n];
21791     return basis((t - i / n) * n, v0, v1, v2, v3);
21792   };
21793 };
21794
21795 var constant$3 = function(x) {
21796   return function() {
21797     return x;
21798   };
21799 };
21800
21801 function linear(a, d) {
21802   return function(t) {
21803     return a + t * d;
21804   };
21805 }
21806
21807 function exponential(a, b, y) {
21808   return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
21809     return Math.pow(a + t * b, y);
21810   };
21811 }
21812
21813 function hue(a, b) {
21814   var d = b - a;
21815   return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
21816 }
21817
21818 function gamma(y) {
21819   return (y = +y) === 1 ? nogamma : function(a, b) {
21820     return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
21821   };
21822 }
21823
21824 function nogamma(a, b) {
21825   var d = b - a;
21826   return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
21827 }
21828
21829 var interpolateRgb = (function rgbGamma(y) {
21830   var color$$1 = gamma(y);
21831
21832   function rgb$$1(start, end) {
21833     var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
21834         g = color$$1(start.g, end.g),
21835         b = color$$1(start.b, end.b),
21836         opacity = nogamma(start.opacity, end.opacity);
21837     return function(t) {
21838       start.r = r(t);
21839       start.g = g(t);
21840       start.b = b(t);
21841       start.opacity = opacity(t);
21842       return start + "";
21843     };
21844   }
21845
21846   rgb$$1.gamma = rgbGamma;
21847
21848   return rgb$$1;
21849 })(1);
21850
21851 function rgbSpline(spline) {
21852   return function(colors) {
21853     var n = colors.length,
21854         r = new Array(n),
21855         g = new Array(n),
21856         b = new Array(n),
21857         i, color$$1;
21858     for (i = 0; i < n; ++i) {
21859       color$$1 = rgb(colors[i]);
21860       r[i] = color$$1.r || 0;
21861       g[i] = color$$1.g || 0;
21862       b[i] = color$$1.b || 0;
21863     }
21864     r = spline(r);
21865     g = spline(g);
21866     b = spline(b);
21867     color$$1.opacity = 1;
21868     return function(t) {
21869       color$$1.r = r(t);
21870       color$$1.g = g(t);
21871       color$$1.b = b(t);
21872       return color$$1 + "";
21873     };
21874   };
21875 }
21876
21877 var rgbBasis = rgbSpline(basis$1);
21878 var rgbBasisClosed = rgbSpline(basisClosed);
21879
21880 var array$1 = function(a, b) {
21881   var nb = b ? b.length : 0,
21882       na = a ? Math.min(nb, a.length) : 0,
21883       x = new Array(nb),
21884       c = new Array(nb),
21885       i;
21886
21887   for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);
21888   for (; i < nb; ++i) c[i] = b[i];
21889
21890   return function(t) {
21891     for (i = 0; i < na; ++i) c[i] = x[i](t);
21892     return c;
21893   };
21894 };
21895
21896 var date = function(a, b) {
21897   var d = new Date;
21898   return a = +a, b -= a, function(t) {
21899     return d.setTime(a + b * t), d;
21900   };
21901 };
21902
21903 var reinterpolate = function(a, b) {
21904   return a = +a, b -= a, function(t) {
21905     return a + b * t;
21906   };
21907 };
21908
21909 var object = function(a, b) {
21910   var i = {},
21911       c = {},
21912       k;
21913
21914   if (a === null || typeof a !== "object") a = {};
21915   if (b === null || typeof b !== "object") b = {};
21916
21917   for (k in b) {
21918     if (k in a) {
21919       i[k] = interpolateValue(a[k], b[k]);
21920     } else {
21921       c[k] = b[k];
21922     }
21923   }
21924
21925   return function(t) {
21926     for (k in i) c[k] = i[k](t);
21927     return c;
21928   };
21929 };
21930
21931 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
21932 var reB = new RegExp(reA.source, "g");
21933
21934 function zero(b) {
21935   return function() {
21936     return b;
21937   };
21938 }
21939
21940 function one(b) {
21941   return function(t) {
21942     return b(t) + "";
21943   };
21944 }
21945
21946 var interpolateString = function(a, b) {
21947   var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
21948       am, // current match in a
21949       bm, // current match in b
21950       bs, // string preceding current number in b, if any
21951       i = -1, // index in s
21952       s = [], // string constants and placeholders
21953       q = []; // number interpolators
21954
21955   // Coerce inputs to strings.
21956   a = a + "", b = b + "";
21957
21958   // Interpolate pairs of numbers in a & b.
21959   while ((am = reA.exec(a))
21960       && (bm = reB.exec(b))) {
21961     if ((bs = bm.index) > bi) { // a string precedes the next number in b
21962       bs = b.slice(bi, bs);
21963       if (s[i]) s[i] += bs; // coalesce with previous string
21964       else s[++i] = bs;
21965     }
21966     if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
21967       if (s[i]) s[i] += bm; // coalesce with previous string
21968       else s[++i] = bm;
21969     } else { // interpolate non-matching numbers
21970       s[++i] = null;
21971       q.push({i: i, x: reinterpolate(am, bm)});
21972     }
21973     bi = reB.lastIndex;
21974   }
21975
21976   // Add remains of b.
21977   if (bi < b.length) {
21978     bs = b.slice(bi);
21979     if (s[i]) s[i] += bs; // coalesce with previous string
21980     else s[++i] = bs;
21981   }
21982
21983   // Special optimization for only a single match.
21984   // Otherwise, interpolate each of the numbers and rejoin the string.
21985   return s.length < 2 ? (q[0]
21986       ? one(q[0].x)
21987       : zero(b))
21988       : (b = q.length, function(t) {
21989           for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
21990           return s.join("");
21991         });
21992 };
21993
21994 var interpolateValue = function(a, b) {
21995   var t = typeof b, c;
21996   return b == null || t === "boolean" ? constant$3(b)
21997       : (t === "number" ? reinterpolate
21998       : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)
21999       : b instanceof color ? interpolateRgb
22000       : b instanceof Date ? date
22001       : Array.isArray(b) ? array$1
22002       : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
22003       : reinterpolate)(a, b);
22004 };
22005
22006 var interpolateRound = function(a, b) {
22007   return a = +a, b -= a, function(t) {
22008     return Math.round(a + b * t);
22009   };
22010 };
22011
22012 var degrees = 180 / Math.PI;
22013
22014 var identity$2 = {
22015   translateX: 0,
22016   translateY: 0,
22017   rotate: 0,
22018   skewX: 0,
22019   scaleX: 1,
22020   scaleY: 1
22021 };
22022
22023 var decompose = function(a, b, c, d, e, f) {
22024   var scaleX, scaleY, skewX;
22025   if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
22026   if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
22027   if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
22028   if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
22029   return {
22030     translateX: e,
22031     translateY: f,
22032     rotate: Math.atan2(b, a) * degrees,
22033     skewX: Math.atan(skewX) * degrees,
22034     scaleX: scaleX,
22035     scaleY: scaleY
22036   };
22037 };
22038
22039 var cssNode;
22040 var cssRoot;
22041 var cssView;
22042 var svgNode;
22043
22044 function parseCss(value) {
22045   if (value === "none") return identity$2;
22046   if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
22047   cssNode.style.transform = value;
22048   value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
22049   cssRoot.removeChild(cssNode);
22050   value = value.slice(7, -1).split(",");
22051   return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
22052 }
22053
22054 function parseSvg(value) {
22055   if (value == null) return identity$2;
22056   if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
22057   svgNode.setAttribute("transform", value);
22058   if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
22059   value = value.matrix;
22060   return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
22061 }
22062
22063 function interpolateTransform(parse, pxComma, pxParen, degParen) {
22064
22065   function pop(s) {
22066     return s.length ? s.pop() + " " : "";
22067   }
22068
22069   function translate(xa, ya, xb, yb, s, q) {
22070     if (xa !== xb || ya !== yb) {
22071       var i = s.push("translate(", null, pxComma, null, pxParen);
22072       q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});
22073     } else if (xb || yb) {
22074       s.push("translate(" + xb + pxComma + yb + pxParen);
22075     }
22076   }
22077
22078   function rotate(a, b, s, q) {
22079     if (a !== b) {
22080       if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
22081       q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: reinterpolate(a, b)});
22082     } else if (b) {
22083       s.push(pop(s) + "rotate(" + b + degParen);
22084     }
22085   }
22086
22087   function skewX(a, b, s, q) {
22088     if (a !== b) {
22089       q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: reinterpolate(a, b)});
22090     } else if (b) {
22091       s.push(pop(s) + "skewX(" + b + degParen);
22092     }
22093   }
22094
22095   function scale(xa, ya, xb, yb, s, q) {
22096     if (xa !== xb || ya !== yb) {
22097       var i = s.push(pop(s) + "scale(", null, ",", null, ")");
22098       q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});
22099     } else if (xb !== 1 || yb !== 1) {
22100       s.push(pop(s) + "scale(" + xb + "," + yb + ")");
22101     }
22102   }
22103
22104   return function(a, b) {
22105     var s = [], // string constants and placeholders
22106         q = []; // number interpolators
22107     a = parse(a), b = parse(b);
22108     translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
22109     rotate(a.rotate, b.rotate, s, q);
22110     skewX(a.skewX, b.skewX, s, q);
22111     scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
22112     a = b = null; // gc
22113     return function(t) {
22114       var i = -1, n = q.length, o;
22115       while (++i < n) s[(o = q[i]).i] = o.x(t);
22116       return s.join("");
22117     };
22118   };
22119 }
22120
22121 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
22122 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
22123
22124 var rho = Math.SQRT2;
22125 var rho2 = 2;
22126 var rho4 = 4;
22127 var epsilon2 = 1e-12;
22128
22129 function cosh(x) {
22130   return ((x = Math.exp(x)) + 1 / x) / 2;
22131 }
22132
22133 function sinh(x) {
22134   return ((x = Math.exp(x)) - 1 / x) / 2;
22135 }
22136
22137 function tanh(x) {
22138   return ((x = Math.exp(2 * x)) - 1) / (x + 1);
22139 }
22140
22141 // p0 = [ux0, uy0, w0]
22142 // p1 = [ux1, uy1, w1]
22143 var interpolateZoom = function(p0, p1) {
22144   var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
22145       ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
22146       dx = ux1 - ux0,
22147       dy = uy1 - uy0,
22148       d2 = dx * dx + dy * dy,
22149       i,
22150       S;
22151
22152   // Special case for u0 ≅ u1.
22153   if (d2 < epsilon2) {
22154     S = Math.log(w1 / w0) / rho;
22155     i = function(t) {
22156       return [
22157         ux0 + t * dx,
22158         uy0 + t * dy,
22159         w0 * Math.exp(rho * t * S)
22160       ];
22161     };
22162   }
22163
22164   // General case.
22165   else {
22166     var d1 = Math.sqrt(d2),
22167         b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
22168         b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
22169         r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
22170         r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
22171     S = (r1 - r0) / rho;
22172     i = function(t) {
22173       var s = t * S,
22174           coshr0 = cosh(r0),
22175           u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
22176       return [
22177         ux0 + u * dx,
22178         uy0 + u * dy,
22179         w0 * coshr0 / cosh(rho * s + r0)
22180       ];
22181     };
22182   }
22183
22184   i.duration = S * 1000;
22185
22186   return i;
22187 };
22188
22189 function hsl$1(hue$$1) {
22190   return function(start, end) {
22191     var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
22192         s = nogamma(start.s, end.s),
22193         l = nogamma(start.l, end.l),
22194         opacity = nogamma(start.opacity, end.opacity);
22195     return function(t) {
22196       start.h = h(t);
22197       start.s = s(t);
22198       start.l = l(t);
22199       start.opacity = opacity(t);
22200       return start + "";
22201     };
22202   }
22203 }
22204
22205 var hsl$2 = hsl$1(hue);
22206 var hslLong = hsl$1(nogamma);
22207
22208 function lab$1(start, end) {
22209   var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
22210       a = nogamma(start.a, end.a),
22211       b = nogamma(start.b, end.b),
22212       opacity = nogamma(start.opacity, end.opacity);
22213   return function(t) {
22214     start.l = l(t);
22215     start.a = a(t);
22216     start.b = b(t);
22217     start.opacity = opacity(t);
22218     return start + "";
22219   };
22220 }
22221
22222 function hcl$1(hue$$1) {
22223   return function(start, end) {
22224     var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
22225         c = nogamma(start.c, end.c),
22226         l = nogamma(start.l, end.l),
22227         opacity = nogamma(start.opacity, end.opacity);
22228     return function(t) {
22229       start.h = h(t);
22230       start.c = c(t);
22231       start.l = l(t);
22232       start.opacity = opacity(t);
22233       return start + "";
22234     };
22235   }
22236 }
22237
22238 var hcl$2 = hcl$1(hue);
22239 var hclLong = hcl$1(nogamma);
22240
22241 function cubehelix$1(hue$$1) {
22242   return (function cubehelixGamma(y) {
22243     y = +y;
22244
22245     function cubehelix$$1(start, end) {
22246       var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
22247           s = nogamma(start.s, end.s),
22248           l = nogamma(start.l, end.l),
22249           opacity = nogamma(start.opacity, end.opacity);
22250       return function(t) {
22251         start.h = h(t);
22252         start.s = s(t);
22253         start.l = l(Math.pow(t, y));
22254         start.opacity = opacity(t);
22255         return start + "";
22256       };
22257     }
22258
22259     cubehelix$$1.gamma = cubehelixGamma;
22260
22261     return cubehelix$$1;
22262   })(1);
22263 }
22264
22265 var cubehelix$2 = cubehelix$1(hue);
22266 var cubehelixLong = cubehelix$1(nogamma);
22267
22268 var quantize = function(interpolator, n) {
22269   var samples = new Array(n);
22270   for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
22271   return samples;
22272 };
22273
22274 var frame = 0;
22275 var timeout = 0;
22276 var interval = 0;
22277 var pokeDelay = 1000;
22278 var taskHead;
22279 var taskTail;
22280 var clockLast = 0;
22281 var clockNow = 0;
22282 var clockSkew = 0;
22283 var clock = typeof performance === "object" && performance.now ? performance : Date;
22284 var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
22285
22286 function now() {
22287   return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
22288 }
22289
22290 function clearNow() {
22291   clockNow = 0;
22292 }
22293
22294 function Timer() {
22295   this._call =
22296   this._time =
22297   this._next = null;
22298 }
22299
22300 Timer.prototype = timer.prototype = {
22301   constructor: Timer,
22302   restart: function(callback, delay, time) {
22303     if (typeof callback !== "function") throw new TypeError("callback is not a function");
22304     time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
22305     if (!this._next && taskTail !== this) {
22306       if (taskTail) taskTail._next = this;
22307       else taskHead = this;
22308       taskTail = this;
22309     }
22310     this._call = callback;
22311     this._time = time;
22312     sleep();
22313   },
22314   stop: function() {
22315     if (this._call) {
22316       this._call = null;
22317       this._time = Infinity;
22318       sleep();
22319     }
22320   }
22321 };
22322
22323 function timer(callback, delay, time) {
22324   var t = new Timer;
22325   t.restart(callback, delay, time);
22326   return t;
22327 }
22328
22329 function timerFlush() {
22330   now(); // Get the current time, if not already set.
22331   ++frame; // Pretend we’ve set an alarm, if we haven’t already.
22332   var t = taskHead, e;
22333   while (t) {
22334     if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
22335     t = t._next;
22336   }
22337   --frame;
22338 }
22339
22340 function wake() {
22341   clockNow = (clockLast = clock.now()) + clockSkew;
22342   frame = timeout = 0;
22343   try {
22344     timerFlush();
22345   } finally {
22346     frame = 0;
22347     nap();
22348     clockNow = 0;
22349   }
22350 }
22351
22352 function poke() {
22353   var now = clock.now(), delay = now - clockLast;
22354   if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
22355 }
22356
22357 function nap() {
22358   var t0, t1 = taskHead, t2, time = Infinity;
22359   while (t1) {
22360     if (t1._call) {
22361       if (time > t1._time) time = t1._time;
22362       t0 = t1, t1 = t1._next;
22363     } else {
22364       t2 = t1._next, t1._next = null;
22365       t1 = t0 ? t0._next = t2 : taskHead = t2;
22366     }
22367   }
22368   taskTail = t0;
22369   sleep(time);
22370 }
22371
22372 function sleep(time) {
22373   if (frame) return; // Soonest alarm already set, or will be.
22374   if (timeout) timeout = clearTimeout(timeout);
22375   var delay = time - clockNow;
22376   if (delay > 24) {
22377     if (time < Infinity) timeout = setTimeout(wake, delay);
22378     if (interval) interval = clearInterval(interval);
22379   } else {
22380     if (!interval) clockLast = clockNow, interval = setInterval(poke, pokeDelay);
22381     frame = 1, setFrame(wake);
22382   }
22383 }
22384
22385 var timeout$1 = function(callback, delay, time) {
22386   var t = new Timer;
22387   delay = delay == null ? 0 : +delay;
22388   t.restart(function(elapsed) {
22389     t.stop();
22390     callback(elapsed + delay);
22391   }, delay, time);
22392   return t;
22393 };
22394
22395 var interval$1 = function(callback, delay, time) {
22396   var t = new Timer, total = delay;
22397   if (delay == null) return t.restart(callback, delay, time), t;
22398   delay = +delay, time = time == null ? now() : +time;
22399   t.restart(function tick(elapsed) {
22400     elapsed += total;
22401     t.restart(tick, total += delay, time);
22402     callback(elapsed);
22403   }, delay, time);
22404   return t;
22405 };
22406
22407 var emptyOn = dispatch("start", "end", "interrupt");
22408 var emptyTween = [];
22409
22410 var CREATED = 0;
22411 var SCHEDULED = 1;
22412 var STARTING = 2;
22413 var STARTED = 3;
22414 var RUNNING = 4;
22415 var ENDING = 5;
22416 var ENDED = 6;
22417
22418 var schedule = function(node, name, id, index, group, timing) {
22419   var schedules = node.__transition;
22420   if (!schedules) node.__transition = {};
22421   else if (id in schedules) return;
22422   create(node, id, {
22423     name: name,
22424     index: index, // For context during callback.
22425     group: group, // For context during callback.
22426     on: emptyOn,
22427     tween: emptyTween,
22428     time: timing.time,
22429     delay: timing.delay,
22430     duration: timing.duration,
22431     ease: timing.ease,
22432     timer: null,
22433     state: CREATED
22434   });
22435 };
22436
22437 function init(node, id) {
22438   var schedule = node.__transition;
22439   if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late");
22440   return schedule;
22441 }
22442
22443 function set$1(node, id) {
22444   var schedule = node.__transition;
22445   if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late");
22446   return schedule;
22447 }
22448
22449 function get$1(node, id) {
22450   var schedule = node.__transition;
22451   if (!schedule || !(schedule = schedule[id])) throw new Error("too late");
22452   return schedule;
22453 }
22454
22455 function create(node, id, self) {
22456   var schedules = node.__transition,
22457       tween;
22458
22459   // Initialize the self timer when the transition is created.
22460   // Note the actual delay is not known until the first callback!
22461   schedules[id] = self;
22462   self.timer = timer(schedule, 0, self.time);
22463
22464   function schedule(elapsed) {
22465     self.state = SCHEDULED;
22466     self.timer.restart(start, self.delay, self.time);
22467
22468     // If the elapsed delay is less than our first sleep, start immediately.
22469     if (self.delay <= elapsed) start(elapsed - self.delay);
22470   }
22471
22472   function start(elapsed) {
22473     var i, j, n, o;
22474
22475     // If the state is not SCHEDULED, then we previously errored on start.
22476     if (self.state !== SCHEDULED) return stop();
22477
22478     for (i in schedules) {
22479       o = schedules[i];
22480       if (o.name !== self.name) continue;
22481
22482       // While this element already has a starting transition during this frame,
22483       // defer starting an interrupting transition until that transition has a
22484       // chance to tick (and possibly end); see d3/d3-transition#54!
22485       if (o.state === STARTED) return timeout$1(start);
22486
22487       // Interrupt the active transition, if any.
22488       // Dispatch the interrupt event.
22489       if (o.state === RUNNING) {
22490         o.state = ENDED;
22491         o.timer.stop();
22492         o.on.call("interrupt", node, node.__data__, o.index, o.group);
22493         delete schedules[i];
22494       }
22495
22496       // Cancel any pre-empted transitions. No interrupt event is dispatched
22497       // because the cancelled transitions never started. Note that this also
22498       // removes this transition from the pending list!
22499       else if (+i < id) {
22500         o.state = ENDED;
22501         o.timer.stop();
22502         delete schedules[i];
22503       }
22504     }
22505
22506     // Defer the first tick to end of the current frame; see d3/d3#1576.
22507     // Note the transition may be canceled after start and before the first tick!
22508     // Note this must be scheduled before the start event; see d3/d3-transition#16!
22509     // Assuming this is successful, subsequent callbacks go straight to tick.
22510     timeout$1(function() {
22511       if (self.state === STARTED) {
22512         self.state = RUNNING;
22513         self.timer.restart(tick, self.delay, self.time);
22514         tick(elapsed);
22515       }
22516     });
22517
22518     // Dispatch the start event.
22519     // Note this must be done before the tween are initialized.
22520     self.state = STARTING;
22521     self.on.call("start", node, node.__data__, self.index, self.group);
22522     if (self.state !== STARTING) return; // interrupted
22523     self.state = STARTED;
22524
22525     // Initialize the tween, deleting null tween.
22526     tween = new Array(n = self.tween.length);
22527     for (i = 0, j = -1; i < n; ++i) {
22528       if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
22529         tween[++j] = o;
22530       }
22531     }
22532     tween.length = j + 1;
22533   }
22534
22535   function tick(elapsed) {
22536     var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
22537         i = -1,
22538         n = tween.length;
22539
22540     while (++i < n) {
22541       tween[i].call(null, t);
22542     }
22543
22544     // Dispatch the end event.
22545     if (self.state === ENDING) {
22546       self.on.call("end", node, node.__data__, self.index, self.group);
22547       stop();
22548     }
22549   }
22550
22551   function stop() {
22552     self.state = ENDED;
22553     self.timer.stop();
22554     delete schedules[id];
22555     for (var i in schedules) return; // eslint-disable-line no-unused-vars
22556     delete node.__transition;
22557   }
22558 }
22559
22560 var interrupt = function(node, name) {
22561   var schedules = node.__transition,
22562       schedule$$1,
22563       active,
22564       empty = true,
22565       i;
22566
22567   if (!schedules) return;
22568
22569   name = name == null ? null : name + "";
22570
22571   for (i in schedules) {
22572     if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; }
22573     active = schedule$$1.state > STARTING && schedule$$1.state < ENDING;
22574     schedule$$1.state = ENDED;
22575     schedule$$1.timer.stop();
22576     if (active) schedule$$1.on.call("interrupt", node, node.__data__, schedule$$1.index, schedule$$1.group);
22577     delete schedules[i];
22578   }
22579
22580   if (empty) delete node.__transition;
22581 };
22582
22583 var selection_interrupt = function(name) {
22584   return this.each(function() {
22585     interrupt(this, name);
22586   });
22587 };
22588
22589 function tweenRemove(id, name) {
22590   var tween0, tween1;
22591   return function() {
22592     var schedule$$1 = set$1(this, id),
22593         tween = schedule$$1.tween;
22594
22595     // If this node shared tween with the previous node,
22596     // just assign the updated shared tween and we’re done!
22597     // Otherwise, copy-on-write.
22598     if (tween !== tween0) {
22599       tween1 = tween0 = tween;
22600       for (var i = 0, n = tween1.length; i < n; ++i) {
22601         if (tween1[i].name === name) {
22602           tween1 = tween1.slice();
22603           tween1.splice(i, 1);
22604           break;
22605         }
22606       }
22607     }
22608
22609     schedule$$1.tween = tween1;
22610   };
22611 }
22612
22613 function tweenFunction(id, name, value) {
22614   var tween0, tween1;
22615   if (typeof value !== "function") throw new Error;
22616   return function() {
22617     var schedule$$1 = set$1(this, id),
22618         tween = schedule$$1.tween;
22619
22620     // If this node shared tween with the previous node,
22621     // just assign the updated shared tween and we’re done!
22622     // Otherwise, copy-on-write.
22623     if (tween !== tween0) {
22624       tween1 = (tween0 = tween).slice();
22625       for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
22626         if (tween1[i].name === name) {
22627           tween1[i] = t;
22628           break;
22629         }
22630       }
22631       if (i === n) tween1.push(t);
22632     }
22633
22634     schedule$$1.tween = tween1;
22635   };
22636 }
22637
22638 var transition_tween = function(name, value) {
22639   var id = this._id;
22640
22641   name += "";
22642
22643   if (arguments.length < 2) {
22644     var tween = get$1(this.node(), id).tween;
22645     for (var i = 0, n = tween.length, t; i < n; ++i) {
22646       if ((t = tween[i]).name === name) {
22647         return t.value;
22648       }
22649     }
22650     return null;
22651   }
22652
22653   return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
22654 };
22655
22656 function tweenValue(transition, name, value) {
22657   var id = transition._id;
22658
22659   transition.each(function() {
22660     var schedule$$1 = set$1(this, id);
22661     (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments);
22662   });
22663
22664   return function(node) {
22665     return get$1(node, id).value[name];
22666   };
22667 }
22668
22669 var interpolate = function(a, b) {
22670   var c;
22671   return (typeof b === "number" ? reinterpolate
22672       : b instanceof color ? interpolateRgb
22673       : (c = color(b)) ? (b = c, interpolateRgb)
22674       : interpolateString)(a, b);
22675 };
22676
22677 function attrRemove$1(name) {
22678   return function() {
22679     this.removeAttribute(name);
22680   };
22681 }
22682
22683 function attrRemoveNS$1(fullname) {
22684   return function() {
22685     this.removeAttributeNS(fullname.space, fullname.local);
22686   };
22687 }
22688
22689 function attrConstant$1(name, interpolate$$1, value1) {
22690   var value00,
22691       interpolate0;
22692   return function() {
22693     var value0 = this.getAttribute(name);
22694     return value0 === value1 ? null
22695         : value0 === value00 ? interpolate0
22696         : interpolate0 = interpolate$$1(value00 = value0, value1);
22697   };
22698 }
22699
22700 function attrConstantNS$1(fullname, interpolate$$1, value1) {
22701   var value00,
22702       interpolate0;
22703   return function() {
22704     var value0 = this.getAttributeNS(fullname.space, fullname.local);
22705     return value0 === value1 ? null
22706         : value0 === value00 ? interpolate0
22707         : interpolate0 = interpolate$$1(value00 = value0, value1);
22708   };
22709 }
22710
22711 function attrFunction$1(name, interpolate$$1, value) {
22712   var value00,
22713       value10,
22714       interpolate0;
22715   return function() {
22716     var value0, value1 = value(this);
22717     if (value1 == null) return void this.removeAttribute(name);
22718     value0 = this.getAttribute(name);
22719     return value0 === value1 ? null
22720         : value0 === value00 && value1 === value10 ? interpolate0
22721         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
22722   };
22723 }
22724
22725 function attrFunctionNS$1(fullname, interpolate$$1, value) {
22726   var value00,
22727       value10,
22728       interpolate0;
22729   return function() {
22730     var value0, value1 = value(this);
22731     if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
22732     value0 = this.getAttributeNS(fullname.space, fullname.local);
22733     return value0 === value1 ? null
22734         : value0 === value00 && value1 === value10 ? interpolate0
22735         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
22736   };
22737 }
22738
22739 var transition_attr = function(name, value) {
22740   var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate;
22741   return this.attrTween(name, typeof value === "function"
22742       ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
22743       : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
22744       : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + ""));
22745 };
22746
22747 function attrTweenNS(fullname, value) {
22748   function tween() {
22749     var node = this, i = value.apply(node, arguments);
22750     return i && function(t) {
22751       node.setAttributeNS(fullname.space, fullname.local, i(t));
22752     };
22753   }
22754   tween._value = value;
22755   return tween;
22756 }
22757
22758 function attrTween(name, value) {
22759   function tween() {
22760     var node = this, i = value.apply(node, arguments);
22761     return i && function(t) {
22762       node.setAttribute(name, i(t));
22763     };
22764   }
22765   tween._value = value;
22766   return tween;
22767 }
22768
22769 var transition_attrTween = function(name, value) {
22770   var key = "attr." + name;
22771   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
22772   if (value == null) return this.tween(key, null);
22773   if (typeof value !== "function") throw new Error;
22774   var fullname = namespace(name);
22775   return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
22776 };
22777
22778 function delayFunction(id, value) {
22779   return function() {
22780     init(this, id).delay = +value.apply(this, arguments);
22781   };
22782 }
22783
22784 function delayConstant(id, value) {
22785   return value = +value, function() {
22786     init(this, id).delay = value;
22787   };
22788 }
22789
22790 var transition_delay = function(value) {
22791   var id = this._id;
22792
22793   return arguments.length
22794       ? this.each((typeof value === "function"
22795           ? delayFunction
22796           : delayConstant)(id, value))
22797       : get$1(this.node(), id).delay;
22798 };
22799
22800 function durationFunction(id, value) {
22801   return function() {
22802     set$1(this, id).duration = +value.apply(this, arguments);
22803   };
22804 }
22805
22806 function durationConstant(id, value) {
22807   return value = +value, function() {
22808     set$1(this, id).duration = value;
22809   };
22810 }
22811
22812 var transition_duration = function(value) {
22813   var id = this._id;
22814
22815   return arguments.length
22816       ? this.each((typeof value === "function"
22817           ? durationFunction
22818           : durationConstant)(id, value))
22819       : get$1(this.node(), id).duration;
22820 };
22821
22822 function easeConstant(id, value) {
22823   if (typeof value !== "function") throw new Error;
22824   return function() {
22825     set$1(this, id).ease = value;
22826   };
22827 }
22828
22829 var transition_ease = function(value) {
22830   var id = this._id;
22831
22832   return arguments.length
22833       ? this.each(easeConstant(id, value))
22834       : get$1(this.node(), id).ease;
22835 };
22836
22837 var transition_filter = function(match) {
22838   if (typeof match !== "function") match = matcher$1(match);
22839
22840   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
22841     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
22842       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
22843         subgroup.push(node);
22844       }
22845     }
22846   }
22847
22848   return new Transition(subgroups, this._parents, this._name, this._id);
22849 };
22850
22851 var transition_merge = function(transition$$1) {
22852   if (transition$$1._id !== this._id) throw new Error;
22853
22854   for (var groups0 = this._groups, groups1 = transition$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
22855     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
22856       if (node = group0[i] || group1[i]) {
22857         merge[i] = node;
22858       }
22859     }
22860   }
22861
22862   for (; j < m0; ++j) {
22863     merges[j] = groups0[j];
22864   }
22865
22866   return new Transition(merges, this._parents, this._name, this._id);
22867 };
22868
22869 function start(name) {
22870   return (name + "").trim().split(/^|\s+/).every(function(t) {
22871     var i = t.indexOf(".");
22872     if (i >= 0) t = t.slice(0, i);
22873     return !t || t === "start";
22874   });
22875 }
22876
22877 function onFunction(id, name, listener) {
22878   var on0, on1, sit = start(name) ? init : set$1;
22879   return function() {
22880     var schedule$$1 = sit(this, id),
22881         on = schedule$$1.on;
22882
22883     // If this node shared a dispatch with the previous node,
22884     // just assign the updated shared dispatch and we’re done!
22885     // Otherwise, copy-on-write.
22886     if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
22887
22888     schedule$$1.on = on1;
22889   };
22890 }
22891
22892 var transition_on = function(name, listener) {
22893   var id = this._id;
22894
22895   return arguments.length < 2
22896       ? get$1(this.node(), id).on.on(name)
22897       : this.each(onFunction(id, name, listener));
22898 };
22899
22900 function removeFunction(id) {
22901   return function() {
22902     var parent = this.parentNode;
22903     for (var i in this.__transition) if (+i !== id) return;
22904     if (parent) parent.removeChild(this);
22905   };
22906 }
22907
22908 var transition_remove = function() {
22909   return this.on("end.remove", removeFunction(this._id));
22910 };
22911
22912 var transition_select = function(select$$1) {
22913   var name = this._name,
22914       id = this._id;
22915
22916   if (typeof select$$1 !== "function") select$$1 = selector(select$$1);
22917
22918   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
22919     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
22920       if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) {
22921         if ("__data__" in node) subnode.__data__ = node.__data__;
22922         subgroup[i] = subnode;
22923         schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
22924       }
22925     }
22926   }
22927
22928   return new Transition(subgroups, this._parents, name, id);
22929 };
22930
22931 var transition_selectAll = function(select$$1) {
22932   var name = this._name,
22933       id = this._id;
22934
22935   if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1);
22936
22937   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
22938     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
22939       if (node = group[i]) {
22940         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) {
22941           if (child = children[k]) {
22942             schedule(child, name, id, k, children, inherit);
22943           }
22944         }
22945         subgroups.push(children);
22946         parents.push(node);
22947       }
22948     }
22949   }
22950
22951   return new Transition(subgroups, parents, name, id);
22952 };
22953
22954 var Selection$1 = selection.prototype.constructor;
22955
22956 var transition_selection = function() {
22957   return new Selection$1(this._groups, this._parents);
22958 };
22959
22960 function styleRemove$1(name, interpolate$$1) {
22961   var value00,
22962       value10,
22963       interpolate0;
22964   return function() {
22965     var value0 = styleValue(this, name),
22966         value1 = (this.style.removeProperty(name), styleValue(this, name));
22967     return value0 === value1 ? null
22968         : value0 === value00 && value1 === value10 ? interpolate0
22969         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
22970   };
22971 }
22972
22973 function styleRemoveEnd(name) {
22974   return function() {
22975     this.style.removeProperty(name);
22976   };
22977 }
22978
22979 function styleConstant$1(name, interpolate$$1, value1) {
22980   var value00,
22981       interpolate0;
22982   return function() {
22983     var value0 = styleValue(this, name);
22984     return value0 === value1 ? null
22985         : value0 === value00 ? interpolate0
22986         : interpolate0 = interpolate$$1(value00 = value0, value1);
22987   };
22988 }
22989
22990 function styleFunction$1(name, interpolate$$1, value) {
22991   var value00,
22992       value10,
22993       interpolate0;
22994   return function() {
22995     var value0 = styleValue(this, name),
22996         value1 = value(this);
22997     if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));
22998     return value0 === value1 ? null
22999         : value0 === value00 && value1 === value10 ? interpolate0
23000         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
23001   };
23002 }
23003
23004 var transition_style = function(name, value, priority) {
23005   var i = (name += "") === "transform" ? interpolateTransformCss : interpolate;
23006   return value == null ? this
23007           .styleTween(name, styleRemove$1(name, i))
23008           .on("end.style." + name, styleRemoveEnd(name))
23009       : this.styleTween(name, typeof value === "function"
23010           ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
23011           : styleConstant$1(name, i, value + ""), priority);
23012 };
23013
23014 function styleTween(name, value, priority) {
23015   function tween() {
23016     var node = this, i = value.apply(node, arguments);
23017     return i && function(t) {
23018       node.style.setProperty(name, i(t), priority);
23019     };
23020   }
23021   tween._value = value;
23022   return tween;
23023 }
23024
23025 var transition_styleTween = function(name, value, priority) {
23026   var key = "style." + (name += "");
23027   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
23028   if (value == null) return this.tween(key, null);
23029   if (typeof value !== "function") throw new Error;
23030   return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
23031 };
23032
23033 function textConstant$1(value) {
23034   return function() {
23035     this.textContent = value;
23036   };
23037 }
23038
23039 function textFunction$1(value) {
23040   return function() {
23041     var value1 = value(this);
23042     this.textContent = value1 == null ? "" : value1;
23043   };
23044 }
23045
23046 var transition_text = function(value) {
23047   return this.tween("text", typeof value === "function"
23048       ? textFunction$1(tweenValue(this, "text", value))
23049       : textConstant$1(value == null ? "" : value + ""));
23050 };
23051
23052 var transition_transition = function() {
23053   var name = this._name,
23054       id0 = this._id,
23055       id1 = newId();
23056
23057   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
23058     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
23059       if (node = group[i]) {
23060         var inherit = get$1(node, id0);
23061         schedule(node, name, id1, i, group, {
23062           time: inherit.time + inherit.delay + inherit.duration,
23063           delay: 0,
23064           duration: inherit.duration,
23065           ease: inherit.ease
23066         });
23067       }
23068     }
23069   }
23070
23071   return new Transition(groups, this._parents, name, id1);
23072 };
23073
23074 var id = 0;
23075
23076 function Transition(groups, parents, name, id) {
23077   this._groups = groups;
23078   this._parents = parents;
23079   this._name = name;
23080   this._id = id;
23081 }
23082
23083 function transition(name) {
23084   return selection().transition(name);
23085 }
23086
23087 function newId() {
23088   return ++id;
23089 }
23090
23091 var selection_prototype = selection.prototype;
23092
23093 Transition.prototype = transition.prototype = {
23094   constructor: Transition,
23095   select: transition_select,
23096   selectAll: transition_selectAll,
23097   filter: transition_filter,
23098   merge: transition_merge,
23099   selection: transition_selection,
23100   transition: transition_transition,
23101   call: selection_prototype.call,
23102   nodes: selection_prototype.nodes,
23103   node: selection_prototype.node,
23104   size: selection_prototype.size,
23105   empty: selection_prototype.empty,
23106   each: selection_prototype.each,
23107   on: transition_on,
23108   attr: transition_attr,
23109   attrTween: transition_attrTween,
23110   style: transition_style,
23111   styleTween: transition_styleTween,
23112   text: transition_text,
23113   remove: transition_remove,
23114   tween: transition_tween,
23115   delay: transition_delay,
23116   duration: transition_duration,
23117   ease: transition_ease
23118 };
23119
23120 function linear$1(t) {
23121   return +t;
23122 }
23123
23124 function quadIn(t) {
23125   return t * t;
23126 }
23127
23128 function quadOut(t) {
23129   return t * (2 - t);
23130 }
23131
23132 function quadInOut(t) {
23133   return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
23134 }
23135
23136 function cubicIn(t) {
23137   return t * t * t;
23138 }
23139
23140 function cubicOut(t) {
23141   return --t * t * t + 1;
23142 }
23143
23144 function cubicInOut(t) {
23145   return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
23146 }
23147
23148 var exponent = 3;
23149
23150 var polyIn = (function custom(e) {
23151   e = +e;
23152
23153   function polyIn(t) {
23154     return Math.pow(t, e);
23155   }
23156
23157   polyIn.exponent = custom;
23158
23159   return polyIn;
23160 })(exponent);
23161
23162 var polyOut = (function custom(e) {
23163   e = +e;
23164
23165   function polyOut(t) {
23166     return 1 - Math.pow(1 - t, e);
23167   }
23168
23169   polyOut.exponent = custom;
23170
23171   return polyOut;
23172 })(exponent);
23173
23174 var polyInOut = (function custom(e) {
23175   e = +e;
23176
23177   function polyInOut(t) {
23178     return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
23179   }
23180
23181   polyInOut.exponent = custom;
23182
23183   return polyInOut;
23184 })(exponent);
23185
23186 var pi = Math.PI;
23187 var halfPi = pi / 2;
23188
23189 function sinIn(t) {
23190   return 1 - Math.cos(t * halfPi);
23191 }
23192
23193 function sinOut(t) {
23194   return Math.sin(t * halfPi);
23195 }
23196
23197 function sinInOut(t) {
23198   return (1 - Math.cos(pi * t)) / 2;
23199 }
23200
23201 function expIn(t) {
23202   return Math.pow(2, 10 * t - 10);
23203 }
23204
23205 function expOut(t) {
23206   return 1 - Math.pow(2, -10 * t);
23207 }
23208
23209 function expInOut(t) {
23210   return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
23211 }
23212
23213 function circleIn(t) {
23214   return 1 - Math.sqrt(1 - t * t);
23215 }
23216
23217 function circleOut(t) {
23218   return Math.sqrt(1 - --t * t);
23219 }
23220
23221 function circleInOut(t) {
23222   return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
23223 }
23224
23225 var b1 = 4 / 11;
23226 var b2 = 6 / 11;
23227 var b3 = 8 / 11;
23228 var b4 = 3 / 4;
23229 var b5 = 9 / 11;
23230 var b6 = 10 / 11;
23231 var b7 = 15 / 16;
23232 var b8 = 21 / 22;
23233 var b9 = 63 / 64;
23234 var b0 = 1 / b1 / b1;
23235
23236 function bounceIn(t) {
23237   return 1 - bounceOut(1 - t);
23238 }
23239
23240 function bounceOut(t) {
23241   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;
23242 }
23243
23244 function bounceInOut(t) {
23245   return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
23246 }
23247
23248 var overshoot = 1.70158;
23249
23250 var backIn = (function custom(s) {
23251   s = +s;
23252
23253   function backIn(t) {
23254     return t * t * ((s + 1) * t - s);
23255   }
23256
23257   backIn.overshoot = custom;
23258
23259   return backIn;
23260 })(overshoot);
23261
23262 var backOut = (function custom(s) {
23263   s = +s;
23264
23265   function backOut(t) {
23266     return --t * t * ((s + 1) * t + s) + 1;
23267   }
23268
23269   backOut.overshoot = custom;
23270
23271   return backOut;
23272 })(overshoot);
23273
23274 var backInOut = (function custom(s) {
23275   s = +s;
23276
23277   function backInOut(t) {
23278     return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
23279   }
23280
23281   backInOut.overshoot = custom;
23282
23283   return backInOut;
23284 })(overshoot);
23285
23286 var tau = 2 * Math.PI;
23287 var amplitude = 1;
23288 var period = 0.3;
23289
23290 var elasticIn = (function custom(a, p) {
23291   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
23292
23293   function elasticIn(t) {
23294     return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
23295   }
23296
23297   elasticIn.amplitude = function(a) { return custom(a, p * tau); };
23298   elasticIn.period = function(p) { return custom(a, p); };
23299
23300   return elasticIn;
23301 })(amplitude, period);
23302
23303 var elasticOut = (function custom(a, p) {
23304   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
23305
23306   function elasticOut(t) {
23307     return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
23308   }
23309
23310   elasticOut.amplitude = function(a) { return custom(a, p * tau); };
23311   elasticOut.period = function(p) { return custom(a, p); };
23312
23313   return elasticOut;
23314 })(amplitude, period);
23315
23316 var elasticInOut = (function custom(a, p) {
23317   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
23318
23319   function elasticInOut(t) {
23320     return ((t = t * 2 - 1) < 0
23321         ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
23322         : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
23323   }
23324
23325   elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
23326   elasticInOut.period = function(p) { return custom(a, p); };
23327
23328   return elasticInOut;
23329 })(amplitude, period);
23330
23331 var defaultTiming = {
23332   time: null, // Set on use.
23333   delay: 0,
23334   duration: 250,
23335   ease: cubicInOut
23336 };
23337
23338 function inherit(node, id) {
23339   var timing;
23340   while (!(timing = node.__transition) || !(timing = timing[id])) {
23341     if (!(node = node.parentNode)) {
23342       return defaultTiming.time = now(), defaultTiming;
23343     }
23344   }
23345   return timing;
23346 }
23347
23348 var selection_transition = function(name) {
23349   var id,
23350       timing;
23351
23352   if (name instanceof Transition) {
23353     id = name._id, name = name._name;
23354   } else {
23355     id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
23356   }
23357
23358   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
23359     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
23360       if (node = group[i]) {
23361         schedule(node, name, id, i, group, timing || inherit(node, id));
23362       }
23363     }
23364   }
23365
23366   return new Transition(groups, this._parents, name, id);
23367 };
23368
23369 selection.prototype.interrupt = selection_interrupt;
23370 selection.prototype.transition = selection_transition;
23371
23372 var root$1 = [null];
23373
23374 var active = function(node, name) {
23375   var schedules = node.__transition,
23376       schedule$$1,
23377       i;
23378
23379   if (schedules) {
23380     name = name == null ? null : name + "";
23381     for (i in schedules) {
23382       if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) {
23383         return new Transition([[node]], root$1, name, +i);
23384       }
23385     }
23386   }
23387
23388   return null;
23389 };
23390
23391 var constant$4 = function(x) {
23392   return function() {
23393     return x;
23394   };
23395 };
23396
23397 var BrushEvent = function(target, type, selection) {
23398   this.target = target;
23399   this.type = type;
23400   this.selection = selection;
23401 };
23402
23403 function nopropagation$1() {
23404   event.stopImmediatePropagation();
23405 }
23406
23407 var noevent$1 = function() {
23408   event.preventDefault();
23409   event.stopImmediatePropagation();
23410 };
23411
23412 var MODE_DRAG = {name: "drag"};
23413 var MODE_SPACE = {name: "space"};
23414 var MODE_HANDLE = {name: "handle"};
23415 var MODE_CENTER = {name: "center"};
23416
23417 var X = {
23418   name: "x",
23419   handles: ["e", "w"].map(type$2),
23420   input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
23421   output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
23422 };
23423
23424 var Y = {
23425   name: "y",
23426   handles: ["n", "s"].map(type$2),
23427   input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
23428   output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
23429 };
23430
23431 var XY = {
23432   name: "xy",
23433   handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type$2),
23434   input: function(xy) { return xy; },
23435   output: function(xy) { return xy; }
23436 };
23437
23438 var cursors = {
23439   overlay: "crosshair",
23440   selection: "move",
23441   n: "ns-resize",
23442   e: "ew-resize",
23443   s: "ns-resize",
23444   w: "ew-resize",
23445   nw: "nwse-resize",
23446   ne: "nesw-resize",
23447   se: "nwse-resize",
23448   sw: "nesw-resize"
23449 };
23450
23451 var flipX = {
23452   e: "w",
23453   w: "e",
23454   nw: "ne",
23455   ne: "nw",
23456   se: "sw",
23457   sw: "se"
23458 };
23459
23460 var flipY = {
23461   n: "s",
23462   s: "n",
23463   nw: "sw",
23464   ne: "se",
23465   se: "ne",
23466   sw: "nw"
23467 };
23468
23469 var signsX = {
23470   overlay: +1,
23471   selection: +1,
23472   n: null,
23473   e: +1,
23474   s: null,
23475   w: -1,
23476   nw: -1,
23477   ne: +1,
23478   se: +1,
23479   sw: -1
23480 };
23481
23482 var signsY = {
23483   overlay: +1,
23484   selection: +1,
23485   n: -1,
23486   e: null,
23487   s: +1,
23488   w: null,
23489   nw: -1,
23490   ne: -1,
23491   se: +1,
23492   sw: +1
23493 };
23494
23495 function type$2(t) {
23496   return {type: t};
23497 }
23498
23499 // Ignore right-click, since that should open the context menu.
23500 function defaultFilter() {
23501   return !event.button;
23502 }
23503
23504 function defaultExtent() {
23505   var svg = this.ownerSVGElement || this;
23506   return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
23507 }
23508
23509 // Like d3.local, but with the name “__brush” rather than auto-generated.
23510 function local$$1(node) {
23511   while (!node.__brush) if (!(node = node.parentNode)) return;
23512   return node.__brush;
23513 }
23514
23515 function empty(extent) {
23516   return extent[0][0] === extent[1][0]
23517       || extent[0][1] === extent[1][1];
23518 }
23519
23520 function brushSelection(node) {
23521   var state = node.__brush;
23522   return state ? state.dim.output(state.selection) : null;
23523 }
23524
23525 function brushX() {
23526   return brush$1(X);
23527 }
23528
23529 function brushY() {
23530   return brush$1(Y);
23531 }
23532
23533 var brush = function() {
23534   return brush$1(XY);
23535 };
23536
23537 function brush$1(dim) {
23538   var extent = defaultExtent,
23539       filter = defaultFilter,
23540       listeners = dispatch(brush, "start", "brush", "end"),
23541       handleSize = 6,
23542       touchending;
23543
23544   function brush(group) {
23545     var overlay = group
23546         .property("__brush", initialize)
23547       .selectAll(".overlay")
23548       .data([type$2("overlay")]);
23549
23550     overlay.enter().append("rect")
23551         .attr("class", "overlay")
23552         .attr("pointer-events", "all")
23553         .attr("cursor", cursors.overlay)
23554       .merge(overlay)
23555         .each(function() {
23556           var extent = local$$1(this).extent;
23557           select(this)
23558               .attr("x", extent[0][0])
23559               .attr("y", extent[0][1])
23560               .attr("width", extent[1][0] - extent[0][0])
23561               .attr("height", extent[1][1] - extent[0][1]);
23562         });
23563
23564     group.selectAll(".selection")
23565       .data([type$2("selection")])
23566       .enter().append("rect")
23567         .attr("class", "selection")
23568         .attr("cursor", cursors.selection)
23569         .attr("fill", "#777")
23570         .attr("fill-opacity", 0.3)
23571         .attr("stroke", "#fff")
23572         .attr("shape-rendering", "crispEdges");
23573
23574     var handle = group.selectAll(".handle")
23575       .data(dim.handles, function(d) { return d.type; });
23576
23577     handle.exit().remove();
23578
23579     handle.enter().append("rect")
23580         .attr("class", function(d) { return "handle handle--" + d.type; })
23581         .attr("cursor", function(d) { return cursors[d.type]; });
23582
23583     group
23584         .each(redraw)
23585         .attr("fill", "none")
23586         .attr("pointer-events", "all")
23587         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
23588         .on("mousedown.brush touchstart.brush", started);
23589   }
23590
23591   brush.move = function(group, selection) {
23592     if (group.selection) {
23593       group
23594           .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
23595           .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
23596           .tween("brush", function() {
23597             var that = this,
23598                 state = that.__brush,
23599                 emit = emitter(that, arguments),
23600                 selection0 = state.selection,
23601                 selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
23602                 i = interpolateValue(selection0, selection1);
23603
23604             function tween(t) {
23605               state.selection = t === 1 && empty(selection1) ? null : i(t);
23606               redraw.call(that);
23607               emit.brush();
23608             }
23609
23610             return selection0 && selection1 ? tween : tween(1);
23611           });
23612     } else {
23613       group
23614           .each(function() {
23615             var that = this,
23616                 args = arguments,
23617                 state = that.__brush,
23618                 selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
23619                 emit = emitter(that, args).beforestart();
23620
23621             interrupt(that);
23622             state.selection = selection1 == null || empty(selection1) ? null : selection1;
23623             redraw.call(that);
23624             emit.start().brush().end();
23625           });
23626     }
23627   };
23628
23629   function redraw() {
23630     var group = select(this),
23631         selection = local$$1(this).selection;
23632
23633     if (selection) {
23634       group.selectAll(".selection")
23635           .style("display", null)
23636           .attr("x", selection[0][0])
23637           .attr("y", selection[0][1])
23638           .attr("width", selection[1][0] - selection[0][0])
23639           .attr("height", selection[1][1] - selection[0][1]);
23640
23641       group.selectAll(".handle")
23642           .style("display", null)
23643           .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
23644           .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
23645           .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
23646           .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
23647     }
23648
23649     else {
23650       group.selectAll(".selection,.handle")
23651           .style("display", "none")
23652           .attr("x", null)
23653           .attr("y", null)
23654           .attr("width", null)
23655           .attr("height", null);
23656     }
23657   }
23658
23659   function emitter(that, args) {
23660     return that.__brush.emitter || new Emitter(that, args);
23661   }
23662
23663   function Emitter(that, args) {
23664     this.that = that;
23665     this.args = args;
23666     this.state = that.__brush;
23667     this.active = 0;
23668   }
23669
23670   Emitter.prototype = {
23671     beforestart: function() {
23672       if (++this.active === 1) this.state.emitter = this, this.starting = true;
23673       return this;
23674     },
23675     start: function() {
23676       if (this.starting) this.starting = false, this.emit("start");
23677       return this;
23678     },
23679     brush: function() {
23680       this.emit("brush");
23681       return this;
23682     },
23683     end: function() {
23684       if (--this.active === 0) delete this.state.emitter, this.emit("end");
23685       return this;
23686     },
23687     emit: function(type) {
23688       customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
23689     }
23690   };
23691
23692   function started() {
23693     if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$1(); }
23694     else if (touchending) return;
23695     if (!filter.apply(this, arguments)) return;
23696
23697     var that = this,
23698         type = event.target.__data__.type,
23699         mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
23700         signX = dim === Y ? null : signsX[type],
23701         signY = dim === X ? null : signsY[type],
23702         state = local$$1(that),
23703         extent = state.extent,
23704         selection = state.selection,
23705         W = extent[0][0], w0, w1,
23706         N = extent[0][1], n0, n1,
23707         E = extent[1][0], e0, e1,
23708         S = extent[1][1], s0, s1,
23709         dx,
23710         dy,
23711         moving,
23712         shifting = signX && signY && event.shiftKey,
23713         lockX,
23714         lockY,
23715         point0 = mouse(that),
23716         point = point0,
23717         emit = emitter(that, arguments).beforestart();
23718
23719     if (type === "overlay") {
23720       state.selection = selection = [
23721         [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
23722         [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
23723       ];
23724     } else {
23725       w0 = selection[0][0];
23726       n0 = selection[0][1];
23727       e0 = selection[1][0];
23728       s0 = selection[1][1];
23729     }
23730
23731     w1 = w0;
23732     n1 = n0;
23733     e1 = e0;
23734     s1 = s0;
23735
23736     var group = select(that)
23737         .attr("pointer-events", "none");
23738
23739     var overlay = group.selectAll(".overlay")
23740         .attr("cursor", cursors[type]);
23741
23742     if (event.touches) {
23743       group
23744           .on("touchmove.brush", moved, true)
23745           .on("touchend.brush touchcancel.brush", ended, true);
23746     } else {
23747       var view = select(event.view)
23748           .on("keydown.brush", keydowned, true)
23749           .on("keyup.brush", keyupped, true)
23750           .on("mousemove.brush", moved, true)
23751           .on("mouseup.brush", ended, true);
23752
23753       dragDisable(event.view);
23754     }
23755
23756     nopropagation$1();
23757     interrupt(that);
23758     redraw.call(that);
23759     emit.start();
23760
23761     function moved() {
23762       var point1 = mouse(that);
23763       if (shifting && !lockX && !lockY) {
23764         if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
23765         else lockX = true;
23766       }
23767       point = point1;
23768       moving = true;
23769       noevent$1();
23770       move();
23771     }
23772
23773     function move() {
23774       var t;
23775
23776       dx = point[0] - point0[0];
23777       dy = point[1] - point0[1];
23778
23779       switch (mode) {
23780         case MODE_SPACE:
23781         case MODE_DRAG: {
23782           if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
23783           if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
23784           break;
23785         }
23786         case MODE_HANDLE: {
23787           if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
23788           else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
23789           if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
23790           else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
23791           break;
23792         }
23793         case MODE_CENTER: {
23794           if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
23795           if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
23796           break;
23797         }
23798       }
23799
23800       if (e1 < w1) {
23801         signX *= -1;
23802         t = w0, w0 = e0, e0 = t;
23803         t = w1, w1 = e1, e1 = t;
23804         if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
23805       }
23806
23807       if (s1 < n1) {
23808         signY *= -1;
23809         t = n0, n0 = s0, s0 = t;
23810         t = n1, n1 = s1, s1 = t;
23811         if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
23812       }
23813
23814       if (state.selection) selection = state.selection; // May be set by brush.move!
23815       if (lockX) w1 = selection[0][0], e1 = selection[1][0];
23816       if (lockY) n1 = selection[0][1], s1 = selection[1][1];
23817
23818       if (selection[0][0] !== w1
23819           || selection[0][1] !== n1
23820           || selection[1][0] !== e1
23821           || selection[1][1] !== s1) {
23822         state.selection = [[w1, n1], [e1, s1]];
23823         redraw.call(that);
23824         emit.brush();
23825       }
23826     }
23827
23828     function ended() {
23829       nopropagation$1();
23830       if (event.touches) {
23831         if (event.touches.length) return;
23832         if (touchending) clearTimeout(touchending);
23833         touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
23834         group.on("touchmove.brush touchend.brush touchcancel.brush", null);
23835       } else {
23836         yesdrag(event.view, moving);
23837         view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
23838       }
23839       group.attr("pointer-events", "all");
23840       overlay.attr("cursor", cursors.overlay);
23841       if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
23842       if (empty(selection)) state.selection = null, redraw.call(that);
23843       emit.end();
23844     }
23845
23846     function keydowned() {
23847       switch (event.keyCode) {
23848         case 16: { // SHIFT
23849           shifting = signX && signY;
23850           break;
23851         }
23852         case 18: { // ALT
23853           if (mode === MODE_HANDLE) {
23854             if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
23855             if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
23856             mode = MODE_CENTER;
23857             move();
23858           }
23859           break;
23860         }
23861         case 32: { // SPACE; takes priority over ALT
23862           if (mode === MODE_HANDLE || mode === MODE_CENTER) {
23863             if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
23864             if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
23865             mode = MODE_SPACE;
23866             overlay.attr("cursor", cursors.selection);
23867             move();
23868           }
23869           break;
23870         }
23871         default: return;
23872       }
23873       noevent$1();
23874     }
23875
23876     function keyupped() {
23877       switch (event.keyCode) {
23878         case 16: { // SHIFT
23879           if (shifting) {
23880             lockX = lockY = shifting = false;
23881             move();
23882           }
23883           break;
23884         }
23885         case 18: { // ALT
23886           if (mode === MODE_CENTER) {
23887             if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
23888             if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
23889             mode = MODE_HANDLE;
23890             move();
23891           }
23892           break;
23893         }
23894         case 32: { // SPACE
23895           if (mode === MODE_SPACE) {
23896             if (event.altKey) {
23897               if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
23898               if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
23899               mode = MODE_CENTER;
23900             } else {
23901               if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
23902               if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
23903               mode = MODE_HANDLE;
23904             }
23905             overlay.attr("cursor", cursors[type]);
23906             move();
23907           }
23908           break;
23909         }
23910         default: return;
23911       }
23912       noevent$1();
23913     }
23914   }
23915
23916   function initialize() {
23917     var state = this.__brush || {selection: null};
23918     state.extent = extent.apply(this, arguments);
23919     state.dim = dim;
23920     return state;
23921   }
23922
23923   brush.extent = function(_) {
23924     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
23925   };
23926
23927   brush.filter = function(_) {
23928     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter;
23929   };
23930
23931   brush.handleSize = function(_) {
23932     return arguments.length ? (handleSize = +_, brush) : handleSize;
23933   };
23934
23935   brush.on = function() {
23936     var value = listeners.on.apply(listeners, arguments);
23937     return value === listeners ? brush : value;
23938   };
23939
23940   return brush;
23941 }
23942
23943 var cos = Math.cos;
23944 var sin = Math.sin;
23945 var pi$1 = Math.PI;
23946 var halfPi$1 = pi$1 / 2;
23947 var tau$1 = pi$1 * 2;
23948 var max$1 = Math.max;
23949
23950 function compareValue(compare) {
23951   return function(a, b) {
23952     return compare(
23953       a.source.value + a.target.value,
23954       b.source.value + b.target.value
23955     );
23956   };
23957 }
23958
23959 var chord = function() {
23960   var padAngle = 0,
23961       sortGroups = null,
23962       sortSubgroups = null,
23963       sortChords = null;
23964
23965   function chord(matrix) {
23966     var n = matrix.length,
23967         groupSums = [],
23968         groupIndex = sequence(n),
23969         subgroupIndex = [],
23970         chords = [],
23971         groups = chords.groups = new Array(n),
23972         subgroups = new Array(n * n),
23973         k,
23974         x,
23975         x0,
23976         dx,
23977         i,
23978         j;
23979
23980     // Compute the sum.
23981     k = 0, i = -1; while (++i < n) {
23982       x = 0, j = -1; while (++j < n) {
23983         x += matrix[i][j];
23984       }
23985       groupSums.push(x);
23986       subgroupIndex.push(sequence(n));
23987       k += x;
23988     }
23989
23990     // Sort groups…
23991     if (sortGroups) groupIndex.sort(function(a, b) {
23992       return sortGroups(groupSums[a], groupSums[b]);
23993     });
23994
23995     // Sort subgroups…
23996     if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
23997       d.sort(function(a, b) {
23998         return sortSubgroups(matrix[i][a], matrix[i][b]);
23999       });
24000     });
24001
24002     // Convert the sum to scaling factor for [0, 2pi].
24003     // TODO Allow start and end angle to be specified?
24004     // TODO Allow padding to be specified as percentage?
24005     k = max$1(0, tau$1 - padAngle * n) / k;
24006     dx = k ? padAngle : tau$1 / n;
24007
24008     // Compute the start and end angle for each group and subgroup.
24009     // Note: Opera has a bug reordering object literal properties!
24010     x = 0, i = -1; while (++i < n) {
24011       x0 = x, j = -1; while (++j < n) {
24012         var di = groupIndex[i],
24013             dj = subgroupIndex[di][j],
24014             v = matrix[di][dj],
24015             a0 = x,
24016             a1 = x += v * k;
24017         subgroups[dj * n + di] = {
24018           index: di,
24019           subindex: dj,
24020           startAngle: a0,
24021           endAngle: a1,
24022           value: v
24023         };
24024       }
24025       groups[di] = {
24026         index: di,
24027         startAngle: x0,
24028         endAngle: x,
24029         value: groupSums[di]
24030       };
24031       x += dx;
24032     }
24033
24034     // Generate chords for each (non-empty) subgroup-subgroup link.
24035     i = -1; while (++i < n) {
24036       j = i - 1; while (++j < n) {
24037         var source = subgroups[j * n + i],
24038             target = subgroups[i * n + j];
24039         if (source.value || target.value) {
24040           chords.push(source.value < target.value
24041               ? {source: target, target: source}
24042               : {source: source, target: target});
24043         }
24044       }
24045     }
24046
24047     return sortChords ? chords.sort(sortChords) : chords;
24048   }
24049
24050   chord.padAngle = function(_) {
24051     return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
24052   };
24053
24054   chord.sortGroups = function(_) {
24055     return arguments.length ? (sortGroups = _, chord) : sortGroups;
24056   };
24057
24058   chord.sortSubgroups = function(_) {
24059     return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
24060   };
24061
24062   chord.sortChords = function(_) {
24063     return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
24064   };
24065
24066   return chord;
24067 };
24068
24069 var slice$2 = Array.prototype.slice;
24070
24071 var constant$5 = function(x) {
24072   return function() {
24073     return x;
24074   };
24075 };
24076
24077 var pi$2 = Math.PI;
24078 var tau$2 = 2 * pi$2;
24079 var epsilon$1 = 1e-6;
24080 var tauEpsilon = tau$2 - epsilon$1;
24081
24082 function Path() {
24083   this._x0 = this._y0 = // start of current subpath
24084   this._x1 = this._y1 = null; // end of current subpath
24085   this._ = "";
24086 }
24087
24088 function path() {
24089   return new Path;
24090 }
24091
24092 Path.prototype = path.prototype = {
24093   constructor: Path,
24094   moveTo: function(x, y) {
24095     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
24096   },
24097   closePath: function() {
24098     if (this._x1 !== null) {
24099       this._x1 = this._x0, this._y1 = this._y0;
24100       this._ += "Z";
24101     }
24102   },
24103   lineTo: function(x, y) {
24104     this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
24105   },
24106   quadraticCurveTo: function(x1, y1, x, y) {
24107     this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
24108   },
24109   bezierCurveTo: function(x1, y1, x2, y2, x, y) {
24110     this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
24111   },
24112   arcTo: function(x1, y1, x2, y2, r) {
24113     x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
24114     var x0 = this._x1,
24115         y0 = this._y1,
24116         x21 = x2 - x1,
24117         y21 = y2 - y1,
24118         x01 = x0 - x1,
24119         y01 = y0 - y1,
24120         l01_2 = x01 * x01 + y01 * y01;
24121
24122     // Is the radius negative? Error.
24123     if (r < 0) throw new Error("negative radius: " + r);
24124
24125     // Is this path empty? Move to (x1,y1).
24126     if (this._x1 === null) {
24127       this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
24128     }
24129
24130     // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
24131     else if (!(l01_2 > epsilon$1)) {}
24132
24133     // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
24134     // Equivalently, is (x1,y1) coincident with (x2,y2)?
24135     // Or, is the radius zero? Line to (x1,y1).
24136     else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
24137       this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
24138     }
24139
24140     // Otherwise, draw an arc!
24141     else {
24142       var x20 = x2 - x0,
24143           y20 = y2 - y0,
24144           l21_2 = x21 * x21 + y21 * y21,
24145           l20_2 = x20 * x20 + y20 * y20,
24146           l21 = Math.sqrt(l21_2),
24147           l01 = Math.sqrt(l01_2),
24148           l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
24149           t01 = l / l01,
24150           t21 = l / l21;
24151
24152       // If the start tangent is not coincident with (x0,y0), line to.
24153       if (Math.abs(t01 - 1) > epsilon$1) {
24154         this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
24155       }
24156
24157       this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
24158     }
24159   },
24160   arc: function(x, y, r, a0, a1, ccw) {
24161     x = +x, y = +y, r = +r;
24162     var dx = r * Math.cos(a0),
24163         dy = r * Math.sin(a0),
24164         x0 = x + dx,
24165         y0 = y + dy,
24166         cw = 1 ^ ccw,
24167         da = ccw ? a0 - a1 : a1 - a0;
24168
24169     // Is the radius negative? Error.
24170     if (r < 0) throw new Error("negative radius: " + r);
24171
24172     // Is this path empty? Move to (x0,y0).
24173     if (this._x1 === null) {
24174       this._ += "M" + x0 + "," + y0;
24175     }
24176
24177     // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
24178     else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {
24179       this._ += "L" + x0 + "," + y0;
24180     }
24181
24182     // Is this arc empty? We’re done.
24183     if (!r) return;
24184
24185     // Does the angle go the wrong way? Flip the direction.
24186     if (da < 0) da = da % tau$2 + tau$2;
24187
24188     // Is this a complete circle? Draw two arcs to complete the circle.
24189     if (da > tauEpsilon) {
24190       this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
24191     }
24192
24193     // Is this arc non-empty? Draw an arc!
24194     else if (da > epsilon$1) {
24195       this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
24196     }
24197   },
24198   rect: function(x, y, w, h) {
24199     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
24200   },
24201   toString: function() {
24202     return this._;
24203   }
24204 };
24205
24206 function defaultSource(d) {
24207   return d.source;
24208 }
24209
24210 function defaultTarget(d) {
24211   return d.target;
24212 }
24213
24214 function defaultRadius(d) {
24215   return d.radius;
24216 }
24217
24218 function defaultStartAngle(d) {
24219   return d.startAngle;
24220 }
24221
24222 function defaultEndAngle(d) {
24223   return d.endAngle;
24224 }
24225
24226 var ribbon = function() {
24227   var source = defaultSource,
24228       target = defaultTarget,
24229       radius = defaultRadius,
24230       startAngle = defaultStartAngle,
24231       endAngle = defaultEndAngle,
24232       context = null;
24233
24234   function ribbon() {
24235     var buffer,
24236         argv = slice$2.call(arguments),
24237         s = source.apply(this, argv),
24238         t = target.apply(this, argv),
24239         sr = +radius.apply(this, (argv[0] = s, argv)),
24240         sa0 = startAngle.apply(this, argv) - halfPi$1,
24241         sa1 = endAngle.apply(this, argv) - halfPi$1,
24242         sx0 = sr * cos(sa0),
24243         sy0 = sr * sin(sa0),
24244         tr = +radius.apply(this, (argv[0] = t, argv)),
24245         ta0 = startAngle.apply(this, argv) - halfPi$1,
24246         ta1 = endAngle.apply(this, argv) - halfPi$1;
24247
24248     if (!context) context = buffer = path();
24249
24250     context.moveTo(sx0, sy0);
24251     context.arc(0, 0, sr, sa0, sa1);
24252     if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
24253       context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
24254       context.arc(0, 0, tr, ta0, ta1);
24255     }
24256     context.quadraticCurveTo(0, 0, sx0, sy0);
24257     context.closePath();
24258
24259     if (buffer) return context = null, buffer + "" || null;
24260   }
24261
24262   ribbon.radius = function(_) {
24263     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius;
24264   };
24265
24266   ribbon.startAngle = function(_) {
24267     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle;
24268   };
24269
24270   ribbon.endAngle = function(_) {
24271     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle;
24272   };
24273
24274   ribbon.source = function(_) {
24275     return arguments.length ? (source = _, ribbon) : source;
24276   };
24277
24278   ribbon.target = function(_) {
24279     return arguments.length ? (target = _, ribbon) : target;
24280   };
24281
24282   ribbon.context = function(_) {
24283     return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;
24284   };
24285
24286   return ribbon;
24287 };
24288
24289 var prefix = "$";
24290
24291 function Map() {}
24292
24293 Map.prototype = map$1.prototype = {
24294   constructor: Map,
24295   has: function(key) {
24296     return (prefix + key) in this;
24297   },
24298   get: function(key) {
24299     return this[prefix + key];
24300   },
24301   set: function(key, value) {
24302     this[prefix + key] = value;
24303     return this;
24304   },
24305   remove: function(key) {
24306     var property = prefix + key;
24307     return property in this && delete this[property];
24308   },
24309   clear: function() {
24310     for (var property in this) if (property[0] === prefix) delete this[property];
24311   },
24312   keys: function() {
24313     var keys = [];
24314     for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
24315     return keys;
24316   },
24317   values: function() {
24318     var values = [];
24319     for (var property in this) if (property[0] === prefix) values.push(this[property]);
24320     return values;
24321   },
24322   entries: function() {
24323     var entries = [];
24324     for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
24325     return entries;
24326   },
24327   size: function() {
24328     var size = 0;
24329     for (var property in this) if (property[0] === prefix) ++size;
24330     return size;
24331   },
24332   empty: function() {
24333     for (var property in this) if (property[0] === prefix) return false;
24334     return true;
24335   },
24336   each: function(f) {
24337     for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
24338   }
24339 };
24340
24341 function map$1(object, f) {
24342   var map = new Map;
24343
24344   // Copy constructor.
24345   if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
24346
24347   // Index array by numeric index or specified key function.
24348   else if (Array.isArray(object)) {
24349     var i = -1,
24350         n = object.length,
24351         o;
24352
24353     if (f == null) while (++i < n) map.set(i, object[i]);
24354     else while (++i < n) map.set(f(o = object[i], i, object), o);
24355   }
24356
24357   // Convert object to map.
24358   else if (object) for (var key in object) map.set(key, object[key]);
24359
24360   return map;
24361 }
24362
24363 var nest = function() {
24364   var keys = [],
24365       sortKeys = [],
24366       sortValues,
24367       rollup,
24368       nest;
24369
24370   function apply(array, depth, createResult, setResult) {
24371     if (depth >= keys.length) {
24372       if (sortValues != null) array.sort(sortValues);
24373       return rollup != null ? rollup(array) : array;
24374     }
24375
24376     var i = -1,
24377         n = array.length,
24378         key = keys[depth++],
24379         keyValue,
24380         value,
24381         valuesByKey = map$1(),
24382         values,
24383         result = createResult();
24384
24385     while (++i < n) {
24386       if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
24387         values.push(value);
24388       } else {
24389         valuesByKey.set(keyValue, [value]);
24390       }
24391     }
24392
24393     valuesByKey.each(function(values, key) {
24394       setResult(result, key, apply(values, depth, createResult, setResult));
24395     });
24396
24397     return result;
24398   }
24399
24400   function entries(map, depth) {
24401     if (++depth > keys.length) return map;
24402     var array, sortKey = sortKeys[depth - 1];
24403     if (rollup != null && depth >= keys.length) array = map.entries();
24404     else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
24405     return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
24406   }
24407
24408   return nest = {
24409     object: function(array) { return apply(array, 0, createObject, setObject); },
24410     map: function(array) { return apply(array, 0, createMap, setMap); },
24411     entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
24412     key: function(d) { keys.push(d); return nest; },
24413     sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
24414     sortValues: function(order) { sortValues = order; return nest; },
24415     rollup: function(f) { rollup = f; return nest; }
24416   };
24417 };
24418
24419 function createObject() {
24420   return {};
24421 }
24422
24423 function setObject(object, key, value) {
24424   object[key] = value;
24425 }
24426
24427 function createMap() {
24428   return map$1();
24429 }
24430
24431 function setMap(map, key, value) {
24432   map.set(key, value);
24433 }
24434
24435 function Set() {}
24436
24437 var proto = map$1.prototype;
24438
24439 Set.prototype = set$2.prototype = {
24440   constructor: Set,
24441   has: proto.has,
24442   add: function(value) {
24443     value += "";
24444     this[prefix + value] = value;
24445     return this;
24446   },
24447   remove: proto.remove,
24448   clear: proto.clear,
24449   values: proto.keys,
24450   size: proto.size,
24451   empty: proto.empty,
24452   each: proto.each
24453 };
24454
24455 function set$2(object, f) {
24456   var set = new Set;
24457
24458   // Copy constructor.
24459   if (object instanceof Set) object.each(function(value) { set.add(value); });
24460
24461   // Otherwise, assume it’s an array.
24462   else if (object) {
24463     var i = -1, n = object.length;
24464     if (f == null) while (++i < n) set.add(object[i]);
24465     else while (++i < n) set.add(f(object[i], i, object));
24466   }
24467
24468   return set;
24469 }
24470
24471 var keys = function(map) {
24472   var keys = [];
24473   for (var key in map) keys.push(key);
24474   return keys;
24475 };
24476
24477 var values = function(map) {
24478   var values = [];
24479   for (var key in map) values.push(map[key]);
24480   return values;
24481 };
24482
24483 var entries = function(map) {
24484   var entries = [];
24485   for (var key in map) entries.push({key: key, value: map[key]});
24486   return entries;
24487 };
24488
24489 function objectConverter(columns) {
24490   return new Function("d", "return {" + columns.map(function(name, i) {
24491     return JSON.stringify(name) + ": d[" + i + "]";
24492   }).join(",") + "}");
24493 }
24494
24495 function customConverter(columns, f) {
24496   var object = objectConverter(columns);
24497   return function(row, i) {
24498     return f(object(row), i, columns);
24499   };
24500 }
24501
24502 // Compute unique columns in order of discovery.
24503 function inferColumns(rows) {
24504   var columnSet = Object.create(null),
24505       columns = [];
24506
24507   rows.forEach(function(row) {
24508     for (var column in row) {
24509       if (!(column in columnSet)) {
24510         columns.push(columnSet[column] = column);
24511       }
24512     }
24513   });
24514
24515   return columns;
24516 }
24517
24518 var dsv = function(delimiter) {
24519   var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
24520       delimiterCode = delimiter.charCodeAt(0);
24521
24522   function parse(text, f) {
24523     var convert, columns, rows = parseRows(text, function(row, i) {
24524       if (convert) return convert(row, i - 1);
24525       columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
24526     });
24527     rows.columns = columns;
24528     return rows;
24529   }
24530
24531   function parseRows(text, f) {
24532     var EOL = {}, // sentinel value for end-of-line
24533         EOF = {}, // sentinel value for end-of-file
24534         rows = [], // output rows
24535         N = text.length,
24536         I = 0, // current character index
24537         n = 0, // the current line number
24538         t, // the current token
24539         eol; // is the current token followed by EOL?
24540
24541     function token() {
24542       if (I >= N) return EOF; // special case: end of file
24543       if (eol) return eol = false, EOL; // special case: end of line
24544
24545       // special case: quotes
24546       var j = I, c;
24547       if (text.charCodeAt(j) === 34) {
24548         var i = j;
24549         while (i++ < N) {
24550           if (text.charCodeAt(i) === 34) {
24551             if (text.charCodeAt(i + 1) !== 34) break;
24552             ++i;
24553           }
24554         }
24555         I = i + 2;
24556         c = text.charCodeAt(i + 1);
24557         if (c === 13) {
24558           eol = true;
24559           if (text.charCodeAt(i + 2) === 10) ++I;
24560         } else if (c === 10) {
24561           eol = true;
24562         }
24563         return text.slice(j + 1, i).replace(/""/g, "\"");
24564       }
24565
24566       // common case: find next delimiter or newline
24567       while (I < N) {
24568         var k = 1;
24569         c = text.charCodeAt(I++);
24570         if (c === 10) eol = true; // \n
24571         else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n
24572         else if (c !== delimiterCode) continue;
24573         return text.slice(j, I - k);
24574       }
24575
24576       // special case: last token before EOF
24577       return text.slice(j);
24578     }
24579
24580     while ((t = token()) !== EOF) {
24581       var a = [];
24582       while (t !== EOL && t !== EOF) {
24583         a.push(t);
24584         t = token();
24585       }
24586       if (f && (a = f(a, n++)) == null) continue;
24587       rows.push(a);
24588     }
24589
24590     return rows;
24591   }
24592
24593   function format(rows, columns) {
24594     if (columns == null) columns = inferColumns(rows);
24595     return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
24596       return columns.map(function(column) {
24597         return formatValue(row[column]);
24598       }).join(delimiter);
24599     })).join("\n");
24600   }
24601
24602   function formatRows(rows) {
24603     return rows.map(formatRow).join("\n");
24604   }
24605
24606   function formatRow(row) {
24607     return row.map(formatValue).join(delimiter);
24608   }
24609
24610   function formatValue(text) {
24611     return text == null ? ""
24612         : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\""
24613         : text;
24614   }
24615
24616   return {
24617     parse: parse,
24618     parseRows: parseRows,
24619     format: format,
24620     formatRows: formatRows
24621   };
24622 };
24623
24624 var csv = dsv(",");
24625
24626 var csvParse = csv.parse;
24627 var csvParseRows = csv.parseRows;
24628 var csvFormat = csv.format;
24629 var csvFormatRows = csv.formatRows;
24630
24631 var tsv = dsv("\t");
24632
24633 var tsvParse = tsv.parse;
24634 var tsvParseRows = tsv.parseRows;
24635 var tsvFormat = tsv.format;
24636 var tsvFormatRows = tsv.formatRows;
24637
24638 var center$1 = function(x, y) {
24639   var nodes;
24640
24641   if (x == null) x = 0;
24642   if (y == null) y = 0;
24643
24644   function force() {
24645     var i,
24646         n = nodes.length,
24647         node,
24648         sx = 0,
24649         sy = 0;
24650
24651     for (i = 0; i < n; ++i) {
24652       node = nodes[i], sx += node.x, sy += node.y;
24653     }
24654
24655     for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
24656       node = nodes[i], node.x -= sx, node.y -= sy;
24657     }
24658   }
24659
24660   force.initialize = function(_) {
24661     nodes = _;
24662   };
24663
24664   force.x = function(_) {
24665     return arguments.length ? (x = +_, force) : x;
24666   };
24667
24668   force.y = function(_) {
24669     return arguments.length ? (y = +_, force) : y;
24670   };
24671
24672   return force;
24673 };
24674
24675 var constant$6 = function(x) {
24676   return function() {
24677     return x;
24678   };
24679 };
24680
24681 var jiggle = function() {
24682   return (Math.random() - 0.5) * 1e-6;
24683 };
24684
24685 var tree_add = function(d) {
24686   var x = +this._x.call(null, d),
24687       y = +this._y.call(null, d);
24688   return add(this.cover(x, y), x, y, d);
24689 };
24690
24691 function add(tree, x, y, d) {
24692   if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
24693
24694   var parent,
24695       node = tree._root,
24696       leaf = {data: d},
24697       x0 = tree._x0,
24698       y0 = tree._y0,
24699       x1 = tree._x1,
24700       y1 = tree._y1,
24701       xm,
24702       ym,
24703       xp,
24704       yp,
24705       right,
24706       bottom,
24707       i,
24708       j;
24709
24710   // If the tree is empty, initialize the root as a leaf.
24711   if (!node) return tree._root = leaf, tree;
24712
24713   // Find the existing leaf for the new point, or add it.
24714   while (node.length) {
24715     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
24716     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
24717     if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
24718   }
24719
24720   // Is the new point is exactly coincident with the existing point?
24721   xp = +tree._x.call(null, node.data);
24722   yp = +tree._y.call(null, node.data);
24723   if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
24724
24725   // Otherwise, split the leaf node until the old and new point are separated.
24726   do {
24727     parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
24728     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
24729     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
24730   } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
24731   return parent[j] = node, parent[i] = leaf, tree;
24732 }
24733
24734 function addAll(data) {
24735   var d, i, n = data.length,
24736       x,
24737       y,
24738       xz = new Array(n),
24739       yz = new Array(n),
24740       x0 = Infinity,
24741       y0 = Infinity,
24742       x1 = -Infinity,
24743       y1 = -Infinity;
24744
24745   // Compute the points and their extent.
24746   for (i = 0; i < n; ++i) {
24747     if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
24748     xz[i] = x;
24749     yz[i] = y;
24750     if (x < x0) x0 = x;
24751     if (x > x1) x1 = x;
24752     if (y < y0) y0 = y;
24753     if (y > y1) y1 = y;
24754   }
24755
24756   // If there were no (valid) points, inherit the existing extent.
24757   if (x1 < x0) x0 = this._x0, x1 = this._x1;
24758   if (y1 < y0) y0 = this._y0, y1 = this._y1;
24759
24760   // Expand the tree to cover the new points.
24761   this.cover(x0, y0).cover(x1, y1);
24762
24763   // Add the new points.
24764   for (i = 0; i < n; ++i) {
24765     add(this, xz[i], yz[i], data[i]);
24766   }
24767
24768   return this;
24769 }
24770
24771 var tree_cover = function(x, y) {
24772   if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
24773
24774   var x0 = this._x0,
24775       y0 = this._y0,
24776       x1 = this._x1,
24777       y1 = this._y1;
24778
24779   // If the quadtree has no extent, initialize them.
24780   // Integer extent are necessary so that if we later double the extent,
24781   // the existing quadrant boundaries don’t change due to floating point error!
24782   if (isNaN(x0)) {
24783     x1 = (x0 = Math.floor(x)) + 1;
24784     y1 = (y0 = Math.floor(y)) + 1;
24785   }
24786
24787   // Otherwise, double repeatedly to cover.
24788   else if (x0 > x || x > x1 || y0 > y || y > y1) {
24789     var z = x1 - x0,
24790         node = this._root,
24791         parent,
24792         i;
24793
24794     switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
24795       case 0: {
24796         do parent = new Array(4), parent[i] = node, node = parent;
24797         while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
24798         break;
24799       }
24800       case 1: {
24801         do parent = new Array(4), parent[i] = node, node = parent;
24802         while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
24803         break;
24804       }
24805       case 2: {
24806         do parent = new Array(4), parent[i] = node, node = parent;
24807         while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
24808         break;
24809       }
24810       case 3: {
24811         do parent = new Array(4), parent[i] = node, node = parent;
24812         while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
24813         break;
24814       }
24815     }
24816
24817     if (this._root && this._root.length) this._root = node;
24818   }
24819
24820   // If the quadtree covers the point already, just return.
24821   else return this;
24822
24823   this._x0 = x0;
24824   this._y0 = y0;
24825   this._x1 = x1;
24826   this._y1 = y1;
24827   return this;
24828 };
24829
24830 var tree_data = function() {
24831   var data = [];
24832   this.visit(function(node) {
24833     if (!node.length) do data.push(node.data); while (node = node.next)
24834   });
24835   return data;
24836 };
24837
24838 var tree_extent = function(_) {
24839   return arguments.length
24840       ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
24841       : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
24842 };
24843
24844 var Quad = function(node, x0, y0, x1, y1) {
24845   this.node = node;
24846   this.x0 = x0;
24847   this.y0 = y0;
24848   this.x1 = x1;
24849   this.y1 = y1;
24850 };
24851
24852 var tree_find = function(x, y, radius) {
24853   var data,
24854       x0 = this._x0,
24855       y0 = this._y0,
24856       x1,
24857       y1,
24858       x2,
24859       y2,
24860       x3 = this._x1,
24861       y3 = this._y1,
24862       quads = [],
24863       node = this._root,
24864       q,
24865       i;
24866
24867   if (node) quads.push(new Quad(node, x0, y0, x3, y3));
24868   if (radius == null) radius = Infinity;
24869   else {
24870     x0 = x - radius, y0 = y - radius;
24871     x3 = x + radius, y3 = y + radius;
24872     radius *= radius;
24873   }
24874
24875   while (q = quads.pop()) {
24876
24877     // Stop searching if this quadrant can’t contain a closer node.
24878     if (!(node = q.node)
24879         || (x1 = q.x0) > x3
24880         || (y1 = q.y0) > y3
24881         || (x2 = q.x1) < x0
24882         || (y2 = q.y1) < y0) continue;
24883
24884     // Bisect the current quadrant.
24885     if (node.length) {
24886       var xm = (x1 + x2) / 2,
24887           ym = (y1 + y2) / 2;
24888
24889       quads.push(
24890         new Quad(node[3], xm, ym, x2, y2),
24891         new Quad(node[2], x1, ym, xm, y2),
24892         new Quad(node[1], xm, y1, x2, ym),
24893         new Quad(node[0], x1, y1, xm, ym)
24894       );
24895
24896       // Visit the closest quadrant first.
24897       if (i = (y >= ym) << 1 | (x >= xm)) {
24898         q = quads[quads.length - 1];
24899         quads[quads.length - 1] = quads[quads.length - 1 - i];
24900         quads[quads.length - 1 - i] = q;
24901       }
24902     }
24903
24904     // Visit this point. (Visiting coincident points isn’t necessary!)
24905     else {
24906       var dx = x - +this._x.call(null, node.data),
24907           dy = y - +this._y.call(null, node.data),
24908           d2 = dx * dx + dy * dy;
24909       if (d2 < radius) {
24910         var d = Math.sqrt(radius = d2);
24911         x0 = x - d, y0 = y - d;
24912         x3 = x + d, y3 = y + d;
24913         data = node.data;
24914       }
24915     }
24916   }
24917
24918   return data;
24919 };
24920
24921 var tree_remove = function(d) {
24922   if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
24923
24924   var parent,
24925       node = this._root,
24926       retainer,
24927       previous,
24928       next,
24929       x0 = this._x0,
24930       y0 = this._y0,
24931       x1 = this._x1,
24932       y1 = this._y1,
24933       x,
24934       y,
24935       xm,
24936       ym,
24937       right,
24938       bottom,
24939       i,
24940       j;
24941
24942   // If the tree is empty, initialize the root as a leaf.
24943   if (!node) return this;
24944
24945   // Find the leaf node for the point.
24946   // While descending, also retain the deepest parent with a non-removed sibling.
24947   if (node.length) while (true) {
24948     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
24949     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
24950     if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
24951     if (!node.length) break;
24952     if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
24953   }
24954
24955   // Find the point to remove.
24956   while (node.data !== d) if (!(previous = node, node = node.next)) return this;
24957   if (next = node.next) delete node.next;
24958
24959   // If there are multiple coincident points, remove just the point.
24960   if (previous) return (next ? previous.next = next : delete previous.next), this;
24961
24962   // If this is the root point, remove it.
24963   if (!parent) return this._root = next, this;
24964
24965   // Remove this leaf.
24966   next ? parent[i] = next : delete parent[i];
24967
24968   // If the parent now contains exactly one leaf, collapse superfluous parents.
24969   if ((node = parent[0] || parent[1] || parent[2] || parent[3])
24970       && node === (parent[3] || parent[2] || parent[1] || parent[0])
24971       && !node.length) {
24972     if (retainer) retainer[j] = node;
24973     else this._root = node;
24974   }
24975
24976   return this;
24977 };
24978
24979 function removeAll(data) {
24980   for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
24981   return this;
24982 }
24983
24984 var tree_root = function() {
24985   return this._root;
24986 };
24987
24988 var tree_size = function() {
24989   var size = 0;
24990   this.visit(function(node) {
24991     if (!node.length) do ++size; while (node = node.next)
24992   });
24993   return size;
24994 };
24995
24996 var tree_visit = function(callback) {
24997   var quads = [], q, node = this._root, child, x0, y0, x1, y1;
24998   if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
24999   while (q = quads.pop()) {
25000     if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
25001       var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
25002       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
25003       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
25004       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
25005       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
25006     }
25007   }
25008   return this;
25009 };
25010
25011 var tree_visitAfter = function(callback) {
25012   var quads = [], next = [], q;
25013   if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
25014   while (q = quads.pop()) {
25015     var node = q.node;
25016     if (node.length) {
25017       var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
25018       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
25019       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
25020       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
25021       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
25022     }
25023     next.push(q);
25024   }
25025   while (q = next.pop()) {
25026     callback(q.node, q.x0, q.y0, q.x1, q.y1);
25027   }
25028   return this;
25029 };
25030
25031 function defaultX(d) {
25032   return d[0];
25033 }
25034
25035 var tree_x = function(_) {
25036   return arguments.length ? (this._x = _, this) : this._x;
25037 };
25038
25039 function defaultY(d) {
25040   return d[1];
25041 }
25042
25043 var tree_y = function(_) {
25044   return arguments.length ? (this._y = _, this) : this._y;
25045 };
25046
25047 function quadtree(nodes, x, y) {
25048   var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
25049   return nodes == null ? tree : tree.addAll(nodes);
25050 }
25051
25052 function Quadtree(x, y, x0, y0, x1, y1) {
25053   this._x = x;
25054   this._y = y;
25055   this._x0 = x0;
25056   this._y0 = y0;
25057   this._x1 = x1;
25058   this._y1 = y1;
25059   this._root = undefined;
25060 }
25061
25062 function leaf_copy(leaf) {
25063   var copy = {data: leaf.data}, next = copy;
25064   while (leaf = leaf.next) next = next.next = {data: leaf.data};
25065   return copy;
25066 }
25067
25068 var treeProto = quadtree.prototype = Quadtree.prototype;
25069
25070 treeProto.copy = function() {
25071   var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
25072       node = this._root,
25073       nodes,
25074       child;
25075
25076   if (!node) return copy;
25077
25078   if (!node.length) return copy._root = leaf_copy(node), copy;
25079
25080   nodes = [{source: node, target: copy._root = new Array(4)}];
25081   while (node = nodes.pop()) {
25082     for (var i = 0; i < 4; ++i) {
25083       if (child = node.source[i]) {
25084         if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
25085         else node.target[i] = leaf_copy(child);
25086       }
25087     }
25088   }
25089
25090   return copy;
25091 };
25092
25093 treeProto.add = tree_add;
25094 treeProto.addAll = addAll;
25095 treeProto.cover = tree_cover;
25096 treeProto.data = tree_data;
25097 treeProto.extent = tree_extent;
25098 treeProto.find = tree_find;
25099 treeProto.remove = tree_remove;
25100 treeProto.removeAll = removeAll;
25101 treeProto.root = tree_root;
25102 treeProto.size = tree_size;
25103 treeProto.visit = tree_visit;
25104 treeProto.visitAfter = tree_visitAfter;
25105 treeProto.x = tree_x;
25106 treeProto.y = tree_y;
25107
25108 function x(d) {
25109   return d.x + d.vx;
25110 }
25111
25112 function y(d) {
25113   return d.y + d.vy;
25114 }
25115
25116 var collide = function(radius) {
25117   var nodes,
25118       radii,
25119       strength = 1,
25120       iterations = 1;
25121
25122   if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius);
25123
25124   function force() {
25125     var i, n = nodes.length,
25126         tree,
25127         node,
25128         xi,
25129         yi,
25130         ri,
25131         ri2;
25132
25133     for (var k = 0; k < iterations; ++k) {
25134       tree = quadtree(nodes, x, y).visitAfter(prepare);
25135       for (i = 0; i < n; ++i) {
25136         node = nodes[i];
25137         ri = radii[node.index], ri2 = ri * ri;
25138         xi = node.x + node.vx;
25139         yi = node.y + node.vy;
25140         tree.visit(apply);
25141       }
25142     }
25143
25144     function apply(quad, x0, y0, x1, y1) {
25145       var data = quad.data, rj = quad.r, r = ri + rj;
25146       if (data) {
25147         if (data.index > node.index) {
25148           var x = xi - data.x - data.vx,
25149               y = yi - data.y - data.vy,
25150               l = x * x + y * y;
25151           if (l < r * r) {
25152             if (x === 0) x = jiggle(), l += x * x;
25153             if (y === 0) y = jiggle(), l += y * y;
25154             l = (r - (l = Math.sqrt(l))) / l * strength;
25155             node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
25156             node.vy += (y *= l) * r;
25157             data.vx -= x * (r = 1 - r);
25158             data.vy -= y * r;
25159           }
25160         }
25161         return;
25162       }
25163       return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
25164     }
25165   }
25166
25167   function prepare(quad) {
25168     if (quad.data) return quad.r = radii[quad.data.index];
25169     for (var i = quad.r = 0; i < 4; ++i) {
25170       if (quad[i] && quad[i].r > quad.r) {
25171         quad.r = quad[i].r;
25172       }
25173     }
25174   }
25175
25176   function initialize() {
25177     if (!nodes) return;
25178     var i, n = nodes.length, node;
25179     radii = new Array(n);
25180     for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
25181   }
25182
25183   force.initialize = function(_) {
25184     nodes = _;
25185     initialize();
25186   };
25187
25188   force.iterations = function(_) {
25189     return arguments.length ? (iterations = +_, force) : iterations;
25190   };
25191
25192   force.strength = function(_) {
25193     return arguments.length ? (strength = +_, force) : strength;
25194   };
25195
25196   force.radius = function(_) {
25197     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
25198   };
25199
25200   return force;
25201 };
25202
25203 function index$3(d) {
25204   return d.index;
25205 }
25206
25207 function find(nodeById, nodeId) {
25208   var node = nodeById.get(nodeId);
25209   if (!node) throw new Error("missing: " + nodeId);
25210   return node;
25211 }
25212
25213 var link = function(links) {
25214   var id = index$3,
25215       strength = defaultStrength,
25216       strengths,
25217       distance = constant$6(30),
25218       distances,
25219       nodes,
25220       count,
25221       bias,
25222       iterations = 1;
25223
25224   if (links == null) links = [];
25225
25226   function defaultStrength(link) {
25227     return 1 / Math.min(count[link.source.index], count[link.target.index]);
25228   }
25229
25230   function force(alpha) {
25231     for (var k = 0, n = links.length; k < iterations; ++k) {
25232       for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
25233         link = links[i], source = link.source, target = link.target;
25234         x = target.x + target.vx - source.x - source.vx || jiggle();
25235         y = target.y + target.vy - source.y - source.vy || jiggle();
25236         l = Math.sqrt(x * x + y * y);
25237         l = (l - distances[i]) / l * alpha * strengths[i];
25238         x *= l, y *= l;
25239         target.vx -= x * (b = bias[i]);
25240         target.vy -= y * b;
25241         source.vx += x * (b = 1 - b);
25242         source.vy += y * b;
25243       }
25244     }
25245   }
25246
25247   function initialize() {
25248     if (!nodes) return;
25249
25250     var i,
25251         n = nodes.length,
25252         m = links.length,
25253         nodeById = map$1(nodes, id),
25254         link;
25255
25256     for (i = 0, count = new Array(n); i < m; ++i) {
25257       link = links[i], link.index = i;
25258       if (typeof link.source !== "object") link.source = find(nodeById, link.source);
25259       if (typeof link.target !== "object") link.target = find(nodeById, link.target);
25260       count[link.source.index] = (count[link.source.index] || 0) + 1;
25261       count[link.target.index] = (count[link.target.index] || 0) + 1;
25262     }
25263
25264     for (i = 0, bias = new Array(m); i < m; ++i) {
25265       link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
25266     }
25267
25268     strengths = new Array(m), initializeStrength();
25269     distances = new Array(m), initializeDistance();
25270   }
25271
25272   function initializeStrength() {
25273     if (!nodes) return;
25274
25275     for (var i = 0, n = links.length; i < n; ++i) {
25276       strengths[i] = +strength(links[i], i, links);
25277     }
25278   }
25279
25280   function initializeDistance() {
25281     if (!nodes) return;
25282
25283     for (var i = 0, n = links.length; i < n; ++i) {
25284       distances[i] = +distance(links[i], i, links);
25285     }
25286   }
25287
25288   force.initialize = function(_) {
25289     nodes = _;
25290     initialize();
25291   };
25292
25293   force.links = function(_) {
25294     return arguments.length ? (links = _, initialize(), force) : links;
25295   };
25296
25297   force.id = function(_) {
25298     return arguments.length ? (id = _, force) : id;
25299   };
25300
25301   force.iterations = function(_) {
25302     return arguments.length ? (iterations = +_, force) : iterations;
25303   };
25304
25305   force.strength = function(_) {
25306     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength;
25307   };
25308
25309   force.distance = function(_) {
25310     return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance;
25311   };
25312
25313   return force;
25314 };
25315
25316 function x$1(d) {
25317   return d.x;
25318 }
25319
25320 function y$1(d) {
25321   return d.y;
25322 }
25323
25324 var initialRadius = 10;
25325 var initialAngle = Math.PI * (3 - Math.sqrt(5));
25326
25327 var simulation = function(nodes) {
25328   var simulation,
25329       alpha = 1,
25330       alphaMin = 0.001,
25331       alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
25332       alphaTarget = 0,
25333       velocityDecay = 0.6,
25334       forces = map$1(),
25335       stepper = timer(step),
25336       event = dispatch("tick", "end");
25337
25338   if (nodes == null) nodes = [];
25339
25340   function step() {
25341     tick();
25342     event.call("tick", simulation);
25343     if (alpha < alphaMin) {
25344       stepper.stop();
25345       event.call("end", simulation);
25346     }
25347   }
25348
25349   function tick() {
25350     var i, n = nodes.length, node;
25351
25352     alpha += (alphaTarget - alpha) * alphaDecay;
25353
25354     forces.each(function(force) {
25355       force(alpha);
25356     });
25357
25358     for (i = 0; i < n; ++i) {
25359       node = nodes[i];
25360       if (node.fx == null) node.x += node.vx *= velocityDecay;
25361       else node.x = node.fx, node.vx = 0;
25362       if (node.fy == null) node.y += node.vy *= velocityDecay;
25363       else node.y = node.fy, node.vy = 0;
25364     }
25365   }
25366
25367   function initializeNodes() {
25368     for (var i = 0, n = nodes.length, node; i < n; ++i) {
25369       node = nodes[i], node.index = i;
25370       if (isNaN(node.x) || isNaN(node.y)) {
25371         var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
25372         node.x = radius * Math.cos(angle);
25373         node.y = radius * Math.sin(angle);
25374       }
25375       if (isNaN(node.vx) || isNaN(node.vy)) {
25376         node.vx = node.vy = 0;
25377       }
25378     }
25379   }
25380
25381   function initializeForce(force) {
25382     if (force.initialize) force.initialize(nodes);
25383     return force;
25384   }
25385
25386   initializeNodes();
25387
25388   return simulation = {
25389     tick: tick,
25390
25391     restart: function() {
25392       return stepper.restart(step), simulation;
25393     },
25394
25395     stop: function() {
25396       return stepper.stop(), simulation;
25397     },
25398
25399     nodes: function(_) {
25400       return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
25401     },
25402
25403     alpha: function(_) {
25404       return arguments.length ? (alpha = +_, simulation) : alpha;
25405     },
25406
25407     alphaMin: function(_) {
25408       return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
25409     },
25410
25411     alphaDecay: function(_) {
25412       return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
25413     },
25414
25415     alphaTarget: function(_) {
25416       return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
25417     },
25418
25419     velocityDecay: function(_) {
25420       return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
25421     },
25422
25423     force: function(name, _) {
25424       return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
25425     },
25426
25427     find: function(x, y, radius) {
25428       var i = 0,
25429           n = nodes.length,
25430           dx,
25431           dy,
25432           d2,
25433           node,
25434           closest;
25435
25436       if (radius == null) radius = Infinity;
25437       else radius *= radius;
25438
25439       for (i = 0; i < n; ++i) {
25440         node = nodes[i];
25441         dx = x - node.x;
25442         dy = y - node.y;
25443         d2 = dx * dx + dy * dy;
25444         if (d2 < radius) closest = node, radius = d2;
25445       }
25446
25447       return closest;
25448     },
25449
25450     on: function(name, _) {
25451       return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
25452     }
25453   };
25454 };
25455
25456 var manyBody = function() {
25457   var nodes,
25458       node,
25459       alpha,
25460       strength = constant$6(-30),
25461       strengths,
25462       distanceMin2 = 1,
25463       distanceMax2 = Infinity,
25464       theta2 = 0.81;
25465
25466   function force(_) {
25467     var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);
25468     for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
25469   }
25470
25471   function initialize() {
25472     if (!nodes) return;
25473     var i, n = nodes.length, node;
25474     strengths = new Array(n);
25475     for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
25476   }
25477
25478   function accumulate(quad) {
25479     var strength = 0, q, c, x, y, i;
25480
25481     // For internal nodes, accumulate forces from child quadrants.
25482     if (quad.length) {
25483       for (x = y = i = 0; i < 4; ++i) {
25484         if ((q = quad[i]) && (c = q.value)) {
25485           strength += c, x += c * q.x, y += c * q.y;
25486         }
25487       }
25488       quad.x = x / strength;
25489       quad.y = y / strength;
25490     }
25491
25492     // For leaf nodes, accumulate forces from coincident quadrants.
25493     else {
25494       q = quad;
25495       q.x = q.data.x;
25496       q.y = q.data.y;
25497       do strength += strengths[q.data.index];
25498       while (q = q.next);
25499     }
25500
25501     quad.value = strength;
25502   }
25503
25504   function apply(quad, x1, _, x2) {
25505     if (!quad.value) return true;
25506
25507     var x = quad.x - node.x,
25508         y = quad.y - node.y,
25509         w = x2 - x1,
25510         l = x * x + y * y;
25511
25512     // Apply the Barnes-Hut approximation if possible.
25513     // Limit forces for very close nodes; randomize direction if coincident.
25514     if (w * w / theta2 < l) {
25515       if (l < distanceMax2) {
25516         if (x === 0) x = jiggle(), l += x * x;
25517         if (y === 0) y = jiggle(), l += y * y;
25518         if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
25519         node.vx += x * quad.value * alpha / l;
25520         node.vy += y * quad.value * alpha / l;
25521       }
25522       return true;
25523     }
25524
25525     // Otherwise, process points directly.
25526     else if (quad.length || l >= distanceMax2) return;
25527
25528     // Limit forces for very close nodes; randomize direction if coincident.
25529     if (quad.data !== node || quad.next) {
25530       if (x === 0) x = jiggle(), l += x * x;
25531       if (y === 0) y = jiggle(), l += y * y;
25532       if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
25533     }
25534
25535     do if (quad.data !== node) {
25536       w = strengths[quad.data.index] * alpha / l;
25537       node.vx += x * w;
25538       node.vy += y * w;
25539     } while (quad = quad.next);
25540   }
25541
25542   force.initialize = function(_) {
25543     nodes = _;
25544     initialize();
25545   };
25546
25547   force.strength = function(_) {
25548     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
25549   };
25550
25551   force.distanceMin = function(_) {
25552     return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
25553   };
25554
25555   force.distanceMax = function(_) {
25556     return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
25557   };
25558
25559   force.theta = function(_) {
25560     return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
25561   };
25562
25563   return force;
25564 };
25565
25566 var x$2 = function(x) {
25567   var strength = constant$6(0.1),
25568       nodes,
25569       strengths,
25570       xz;
25571
25572   if (typeof x !== "function") x = constant$6(x == null ? 0 : +x);
25573
25574   function force(alpha) {
25575     for (var i = 0, n = nodes.length, node; i < n; ++i) {
25576       node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
25577     }
25578   }
25579
25580   function initialize() {
25581     if (!nodes) return;
25582     var i, n = nodes.length;
25583     strengths = new Array(n);
25584     xz = new Array(n);
25585     for (i = 0; i < n; ++i) {
25586       strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
25587     }
25588   }
25589
25590   force.initialize = function(_) {
25591     nodes = _;
25592     initialize();
25593   };
25594
25595   force.strength = function(_) {
25596     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
25597   };
25598
25599   force.x = function(_) {
25600     return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x;
25601   };
25602
25603   return force;
25604 };
25605
25606 var y$2 = function(y) {
25607   var strength = constant$6(0.1),
25608       nodes,
25609       strengths,
25610       yz;
25611
25612   if (typeof y !== "function") y = constant$6(y == null ? 0 : +y);
25613
25614   function force(alpha) {
25615     for (var i = 0, n = nodes.length, node; i < n; ++i) {
25616       node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
25617     }
25618   }
25619
25620   function initialize() {
25621     if (!nodes) return;
25622     var i, n = nodes.length;
25623     strengths = new Array(n);
25624     yz = new Array(n);
25625     for (i = 0; i < n; ++i) {
25626       strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
25627     }
25628   }
25629
25630   force.initialize = function(_) {
25631     nodes = _;
25632     initialize();
25633   };
25634
25635   force.strength = function(_) {
25636     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
25637   };
25638
25639   force.y = function(_) {
25640     return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y;
25641   };
25642
25643   return force;
25644 };
25645
25646 // Computes the decimal coefficient and exponent of the specified number x with
25647 // significant digits p, where x is positive and p is in [1, 21] or undefined.
25648 // For example, formatDecimal(1.23) returns ["123", 0].
25649 var formatDecimal = function(x, p) {
25650   if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
25651   var i, coefficient = x.slice(0, i);
25652
25653   // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
25654   // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
25655   return [
25656     coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
25657     +x.slice(i + 1)
25658   ];
25659 };
25660
25661 var exponent$1 = function(x) {
25662   return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
25663 };
25664
25665 var formatGroup = function(grouping, thousands) {
25666   return function(value, width) {
25667     var i = value.length,
25668         t = [],
25669         j = 0,
25670         g = grouping[0],
25671         length = 0;
25672
25673     while (i > 0 && g > 0) {
25674       if (length + g + 1 > width) g = Math.max(1, width - length);
25675       t.push(value.substring(i -= g, i + g));
25676       if ((length += g + 1) > width) break;
25677       g = grouping[j = (j + 1) % grouping.length];
25678     }
25679
25680     return t.reverse().join(thousands);
25681   };
25682 };
25683
25684 var formatNumerals = function(numerals) {
25685   return function(value) {
25686     return value.replace(/[0-9]/g, function(i) {
25687       return numerals[+i];
25688     });
25689   };
25690 };
25691
25692 var formatDefault = function(x, p) {
25693   x = x.toPrecision(p);
25694
25695   out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
25696     switch (x[i]) {
25697       case ".": i0 = i1 = i; break;
25698       case "0": if (i0 === 0) i0 = i; i1 = i; break;
25699       case "e": break out;
25700       default: if (i0 > 0) i0 = 0; break;
25701     }
25702   }
25703
25704   return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
25705 };
25706
25707 var prefixExponent;
25708
25709 var formatPrefixAuto = function(x, p) {
25710   var d = formatDecimal(x, p);
25711   if (!d) return x + "";
25712   var coefficient = d[0],
25713       exponent = d[1],
25714       i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
25715       n = coefficient.length;
25716   return i === n ? coefficient
25717       : i > n ? coefficient + new Array(i - n + 1).join("0")
25718       : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
25719       : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
25720 };
25721
25722 var formatRounded = function(x, p) {
25723   var d = formatDecimal(x, p);
25724   if (!d) return x + "";
25725   var coefficient = d[0],
25726       exponent = d[1];
25727   return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
25728       : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
25729       : coefficient + new Array(exponent - coefficient.length + 2).join("0");
25730 };
25731
25732 var formatTypes = {
25733   "": formatDefault,
25734   "%": function(x, p) { return (x * 100).toFixed(p); },
25735   "b": function(x) { return Math.round(x).toString(2); },
25736   "c": function(x) { return x + ""; },
25737   "d": function(x) { return Math.round(x).toString(10); },
25738   "e": function(x, p) { return x.toExponential(p); },
25739   "f": function(x, p) { return x.toFixed(p); },
25740   "g": function(x, p) { return x.toPrecision(p); },
25741   "o": function(x) { return Math.round(x).toString(8); },
25742   "p": function(x, p) { return formatRounded(x * 100, p); },
25743   "r": formatRounded,
25744   "s": formatPrefixAuto,
25745   "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
25746   "x": function(x) { return Math.round(x).toString(16); }
25747 };
25748
25749 // [[fill]align][sign][symbol][0][width][,][.precision][type]
25750 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
25751
25752 function formatSpecifier(specifier) {
25753   return new FormatSpecifier(specifier);
25754 }
25755
25756 formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
25757
25758 function FormatSpecifier(specifier) {
25759   if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
25760
25761   var match,
25762       fill = match[1] || " ",
25763       align = match[2] || ">",
25764       sign = match[3] || "-",
25765       symbol = match[4] || "",
25766       zero = !!match[5],
25767       width = match[6] && +match[6],
25768       comma = !!match[7],
25769       precision = match[8] && +match[8].slice(1),
25770       type = match[9] || "";
25771
25772   // The "n" type is an alias for ",g".
25773   if (type === "n") comma = true, type = "g";
25774
25775   // Map invalid types to the default format.
25776   else if (!formatTypes[type]) type = "";
25777
25778   // If zero fill is specified, padding goes after sign and before digits.
25779   if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
25780
25781   this.fill = fill;
25782   this.align = align;
25783   this.sign = sign;
25784   this.symbol = symbol;
25785   this.zero = zero;
25786   this.width = width;
25787   this.comma = comma;
25788   this.precision = precision;
25789   this.type = type;
25790 }
25791
25792 FormatSpecifier.prototype.toString = function() {
25793   return this.fill
25794       + this.align
25795       + this.sign
25796       + this.symbol
25797       + (this.zero ? "0" : "")
25798       + (this.width == null ? "" : Math.max(1, this.width | 0))
25799       + (this.comma ? "," : "")
25800       + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
25801       + this.type;
25802 };
25803
25804 var identity$3 = function(x) {
25805   return x;
25806 };
25807
25808 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
25809
25810 var formatLocale = function(locale) {
25811   var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
25812       currency = locale.currency,
25813       decimal = locale.decimal,
25814       numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,
25815       percent = locale.percent || "%";
25816
25817   function newFormat(specifier) {
25818     specifier = formatSpecifier(specifier);
25819
25820     var fill = specifier.fill,
25821         align = specifier.align,
25822         sign = specifier.sign,
25823         symbol = specifier.symbol,
25824         zero = specifier.zero,
25825         width = specifier.width,
25826         comma = specifier.comma,
25827         precision = specifier.precision,
25828         type = specifier.type;
25829
25830     // Compute the prefix and suffix.
25831     // For SI-prefix, the suffix is lazily computed.
25832     var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
25833         suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : "";
25834
25835     // What format function should we use?
25836     // Is this an integer type?
25837     // Can this type generate exponential notation?
25838     var formatType = formatTypes[type],
25839         maybeSuffix = !type || /[defgprs%]/.test(type);
25840
25841     // Set the default precision if not specified,
25842     // or clamp the specified precision to the supported range.
25843     // For significant precision, it must be in [1, 21].
25844     // For fixed precision, it must be in [0, 20].
25845     precision = precision == null ? (type ? 6 : 12)
25846         : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
25847         : Math.max(0, Math.min(20, precision));
25848
25849     function format(value) {
25850       var valuePrefix = prefix,
25851           valueSuffix = suffix,
25852           i, n, c;
25853
25854       if (type === "c") {
25855         valueSuffix = formatType(value) + valueSuffix;
25856         value = "";
25857       } else {
25858         value = +value;
25859
25860         // Perform the initial formatting.
25861         var valueNegative = value < 0;
25862         value = formatType(Math.abs(value), precision);
25863
25864         // If a negative value rounds to zero during formatting, treat as positive.
25865         if (valueNegative && +value === 0) valueNegative = false;
25866
25867         // Compute the prefix and suffix.
25868         valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
25869         valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
25870
25871         // Break the formatted value into the integer “value” part that can be
25872         // grouped, and fractional or exponential “suffix” part that is not.
25873         if (maybeSuffix) {
25874           i = -1, n = value.length;
25875           while (++i < n) {
25876             if (c = value.charCodeAt(i), 48 > c || c > 57) {
25877               valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
25878               value = value.slice(0, i);
25879               break;
25880             }
25881           }
25882         }
25883       }
25884
25885       // If the fill character is not "0", grouping is applied before padding.
25886       if (comma && !zero) value = group(value, Infinity);
25887
25888       // Compute the padding.
25889       var length = valuePrefix.length + value.length + valueSuffix.length,
25890           padding = length < width ? new Array(width - length + 1).join(fill) : "";
25891
25892       // If the fill character is "0", grouping is applied after padding.
25893       if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
25894
25895       // Reconstruct the final output based on the desired alignment.
25896       switch (align) {
25897         case "<": value = valuePrefix + value + valueSuffix + padding; break;
25898         case "=": value = valuePrefix + padding + value + valueSuffix; break;
25899         case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
25900         default: value = padding + valuePrefix + value + valueSuffix; break;
25901       }
25902
25903       return numerals(value);
25904     }
25905
25906     format.toString = function() {
25907       return specifier + "";
25908     };
25909
25910     return format;
25911   }
25912
25913   function formatPrefix(specifier, value) {
25914     var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
25915         e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
25916         k = Math.pow(10, -e),
25917         prefix = prefixes[8 + e / 3];
25918     return function(value) {
25919       return f(k * value) + prefix;
25920     };
25921   }
25922
25923   return {
25924     format: newFormat,
25925     formatPrefix: formatPrefix
25926   };
25927 };
25928
25929 var locale$1;
25930 var format;
25931 var formatPrefix;
25932
25933 defaultLocale({
25934   decimal: ".",
25935   thousands: ",",
25936   grouping: [3],
25937   currency: ["$", ""]
25938 });
25939
25940 function defaultLocale(definition) {
25941   locale$1 = formatLocale(definition);
25942   format = locale$1.format;
25943   formatPrefix = locale$1.formatPrefix;
25944   return locale$1;
25945 }
25946
25947 var precisionFixed = function(step) {
25948   return Math.max(0, -exponent$1(Math.abs(step)));
25949 };
25950
25951 var precisionPrefix = function(step, value) {
25952   return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
25953 };
25954
25955 var precisionRound = function(step, max) {
25956   step = Math.abs(step), max = Math.abs(max) - step;
25957   return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
25958 };
25959
25960 // Adds floating point numbers with twice the normal precision.
25961 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
25962 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
25963 // 305–363 (1997).
25964 // Code adapted from GeographicLib by Charles F. F. Karney,
25965 // http://geographiclib.sourceforge.net/
25966
25967 var adder = function() {
25968   return new Adder;
25969 };
25970
25971 function Adder() {
25972   this.reset();
25973 }
25974
25975 Adder.prototype = {
25976   constructor: Adder,
25977   reset: function() {
25978     this.s = // rounded value
25979     this.t = 0; // exact error
25980   },
25981   add: function(y) {
25982     add$1(temp, y, this.t);
25983     add$1(this, temp.s, this.s);
25984     if (this.s) this.t += temp.t;
25985     else this.s = temp.t;
25986   },
25987   valueOf: function() {
25988     return this.s;
25989   }
25990 };
25991
25992 var temp = new Adder;
25993
25994 function add$1(adder, a, b) {
25995   var x = adder.s = a + b,
25996       bv = x - a,
25997       av = x - bv;
25998   adder.t = (a - av) + (b - bv);
25999 }
26000
26001 var epsilon$2 = 1e-6;
26002 var epsilon2$1 = 1e-12;
26003 var pi$3 = Math.PI;
26004 var halfPi$2 = pi$3 / 2;
26005 var quarterPi = pi$3 / 4;
26006 var tau$3 = pi$3 * 2;
26007
26008 var degrees$1 = 180 / pi$3;
26009 var radians = pi$3 / 180;
26010
26011 var abs = Math.abs;
26012 var atan = Math.atan;
26013 var atan2 = Math.atan2;
26014 var cos$1 = Math.cos;
26015 var ceil = Math.ceil;
26016 var exp = Math.exp;
26017
26018 var log = Math.log;
26019 var pow = Math.pow;
26020 var sin$1 = Math.sin;
26021 var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
26022 var sqrt = Math.sqrt;
26023 var tan = Math.tan;
26024
26025 function acos(x) {
26026   return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
26027 }
26028
26029 function asin(x) {
26030   return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
26031 }
26032
26033 function haversin(x) {
26034   return (x = sin$1(x / 2)) * x;
26035 }
26036
26037 function noop$1() {}
26038
26039 function streamGeometry(geometry, stream) {
26040   if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
26041     streamGeometryType[geometry.type](geometry, stream);
26042   }
26043 }
26044
26045 var streamObjectType = {
26046   Feature: function(object, stream) {
26047     streamGeometry(object.geometry, stream);
26048   },
26049   FeatureCollection: function(object, stream) {
26050     var features = object.features, i = -1, n = features.length;
26051     while (++i < n) streamGeometry(features[i].geometry, stream);
26052   }
26053 };
26054
26055 var streamGeometryType = {
26056   Sphere: function(object, stream) {
26057     stream.sphere();
26058   },
26059   Point: function(object, stream) {
26060     object = object.coordinates;
26061     stream.point(object[0], object[1], object[2]);
26062   },
26063   MultiPoint: function(object, stream) {
26064     var coordinates = object.coordinates, i = -1, n = coordinates.length;
26065     while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
26066   },
26067   LineString: function(object, stream) {
26068     streamLine(object.coordinates, stream, 0);
26069   },
26070   MultiLineString: function(object, stream) {
26071     var coordinates = object.coordinates, i = -1, n = coordinates.length;
26072     while (++i < n) streamLine(coordinates[i], stream, 0);
26073   },
26074   Polygon: function(object, stream) {
26075     streamPolygon(object.coordinates, stream);
26076   },
26077   MultiPolygon: function(object, stream) {
26078     var coordinates = object.coordinates, i = -1, n = coordinates.length;
26079     while (++i < n) streamPolygon(coordinates[i], stream);
26080   },
26081   GeometryCollection: function(object, stream) {
26082     var geometries = object.geometries, i = -1, n = geometries.length;
26083     while (++i < n) streamGeometry(geometries[i], stream);
26084   }
26085 };
26086
26087 function streamLine(coordinates, stream, closed) {
26088   var i = -1, n = coordinates.length - closed, coordinate;
26089   stream.lineStart();
26090   while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
26091   stream.lineEnd();
26092 }
26093
26094 function streamPolygon(coordinates, stream) {
26095   var i = -1, n = coordinates.length;
26096   stream.polygonStart();
26097   while (++i < n) streamLine(coordinates[i], stream, 1);
26098   stream.polygonEnd();
26099 }
26100
26101 var geoStream = function(object, stream) {
26102   if (object && streamObjectType.hasOwnProperty(object.type)) {
26103     streamObjectType[object.type](object, stream);
26104   } else {
26105     streamGeometry(object, stream);
26106   }
26107 };
26108
26109 var areaRingSum = adder();
26110
26111 var areaSum = adder();
26112 var lambda00;
26113 var phi00;
26114 var lambda0;
26115 var cosPhi0;
26116 var sinPhi0;
26117
26118 var areaStream = {
26119   point: noop$1,
26120   lineStart: noop$1,
26121   lineEnd: noop$1,
26122   polygonStart: function() {
26123     areaRingSum.reset();
26124     areaStream.lineStart = areaRingStart;
26125     areaStream.lineEnd = areaRingEnd;
26126   },
26127   polygonEnd: function() {
26128     var areaRing = +areaRingSum;
26129     areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
26130     this.lineStart = this.lineEnd = this.point = noop$1;
26131   },
26132   sphere: function() {
26133     areaSum.add(tau$3);
26134   }
26135 };
26136
26137 function areaRingStart() {
26138   areaStream.point = areaPointFirst;
26139 }
26140
26141 function areaRingEnd() {
26142   areaPoint(lambda00, phi00);
26143 }
26144
26145 function areaPointFirst(lambda, phi) {
26146   areaStream.point = areaPoint;
26147   lambda00 = lambda, phi00 = phi;
26148   lambda *= radians, phi *= radians;
26149   lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
26150 }
26151
26152 function areaPoint(lambda, phi) {
26153   lambda *= radians, phi *= radians;
26154   phi = phi / 2 + quarterPi; // half the angular distance from south pole
26155
26156   // Spherical excess E for a spherical triangle with vertices: south pole,
26157   // previous point, current point.  Uses a formula derived from Cagnoli’s
26158   // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
26159   var dLambda = lambda - lambda0,
26160       sdLambda = dLambda >= 0 ? 1 : -1,
26161       adLambda = sdLambda * dLambda,
26162       cosPhi = cos$1(phi),
26163       sinPhi = sin$1(phi),
26164       k = sinPhi0 * sinPhi,
26165       u = cosPhi0 * cosPhi + k * cos$1(adLambda),
26166       v = k * sdLambda * sin$1(adLambda);
26167   areaRingSum.add(atan2(v, u));
26168
26169   // Advance the previous points.
26170   lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
26171 }
26172
26173 var area = function(object) {
26174   areaSum.reset();
26175   geoStream(object, areaStream);
26176   return areaSum * 2;
26177 };
26178
26179 function spherical(cartesian) {
26180   return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
26181 }
26182
26183 function cartesian(spherical) {
26184   var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
26185   return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
26186 }
26187
26188 function cartesianDot(a, b) {
26189   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
26190 }
26191
26192 function cartesianCross(a, b) {
26193   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]];
26194 }
26195
26196 // TODO return a
26197 function cartesianAddInPlace(a, b) {
26198   a[0] += b[0], a[1] += b[1], a[2] += b[2];
26199 }
26200
26201 function cartesianScale(vector, k) {
26202   return [vector[0] * k, vector[1] * k, vector[2] * k];
26203 }
26204
26205 // TODO return d
26206 function cartesianNormalizeInPlace(d) {
26207   var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
26208   d[0] /= l, d[1] /= l, d[2] /= l;
26209 }
26210
26211 var lambda0$1;
26212 var phi0;
26213 var lambda1;
26214 var phi1;
26215 var lambda2;
26216 var lambda00$1;
26217 var phi00$1;
26218 var p0;
26219 var deltaSum = adder();
26220 var ranges;
26221 var range;
26222
26223 var boundsStream = {
26224   point: boundsPoint,
26225   lineStart: boundsLineStart,
26226   lineEnd: boundsLineEnd,
26227   polygonStart: function() {
26228     boundsStream.point = boundsRingPoint;
26229     boundsStream.lineStart = boundsRingStart;
26230     boundsStream.lineEnd = boundsRingEnd;
26231     deltaSum.reset();
26232     areaStream.polygonStart();
26233   },
26234   polygonEnd: function() {
26235     areaStream.polygonEnd();
26236     boundsStream.point = boundsPoint;
26237     boundsStream.lineStart = boundsLineStart;
26238     boundsStream.lineEnd = boundsLineEnd;
26239     if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
26240     else if (deltaSum > epsilon$2) phi1 = 90;
26241     else if (deltaSum < -epsilon$2) phi0 = -90;
26242     range[0] = lambda0$1, range[1] = lambda1;
26243   }
26244 };
26245
26246 function boundsPoint(lambda, phi) {
26247   ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
26248   if (phi < phi0) phi0 = phi;
26249   if (phi > phi1) phi1 = phi;
26250 }
26251
26252 function linePoint(lambda, phi) {
26253   var p = cartesian([lambda * radians, phi * radians]);
26254   if (p0) {
26255     var normal = cartesianCross(p0, p),
26256         equatorial = [normal[1], -normal[0], 0],
26257         inflection = cartesianCross(equatorial, normal);
26258     cartesianNormalizeInPlace(inflection);
26259     inflection = spherical(inflection);
26260     var delta = lambda - lambda2,
26261         sign$$1 = delta > 0 ? 1 : -1,
26262         lambdai = inflection[0] * degrees$1 * sign$$1,
26263         phii,
26264         antimeridian = abs(delta) > 180;
26265     if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
26266       phii = inflection[1] * degrees$1;
26267       if (phii > phi1) phi1 = phii;
26268     } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
26269       phii = -inflection[1] * degrees$1;
26270       if (phii < phi0) phi0 = phii;
26271     } else {
26272       if (phi < phi0) phi0 = phi;
26273       if (phi > phi1) phi1 = phi;
26274     }
26275     if (antimeridian) {
26276       if (lambda < lambda2) {
26277         if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
26278       } else {
26279         if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
26280       }
26281     } else {
26282       if (lambda1 >= lambda0$1) {
26283         if (lambda < lambda0$1) lambda0$1 = lambda;
26284         if (lambda > lambda1) lambda1 = lambda;
26285       } else {
26286         if (lambda > lambda2) {
26287           if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
26288         } else {
26289           if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
26290         }
26291       }
26292     }
26293   } else {
26294     ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
26295   }
26296   if (phi < phi0) phi0 = phi;
26297   if (phi > phi1) phi1 = phi;
26298   p0 = p, lambda2 = lambda;
26299 }
26300
26301 function boundsLineStart() {
26302   boundsStream.point = linePoint;
26303 }
26304
26305 function boundsLineEnd() {
26306   range[0] = lambda0$1, range[1] = lambda1;
26307   boundsStream.point = boundsPoint;
26308   p0 = null;
26309 }
26310
26311 function boundsRingPoint(lambda, phi) {
26312   if (p0) {
26313     var delta = lambda - lambda2;
26314     deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
26315   } else {
26316     lambda00$1 = lambda, phi00$1 = phi;
26317   }
26318   areaStream.point(lambda, phi);
26319   linePoint(lambda, phi);
26320 }
26321
26322 function boundsRingStart() {
26323   areaStream.lineStart();
26324 }
26325
26326 function boundsRingEnd() {
26327   boundsRingPoint(lambda00$1, phi00$1);
26328   areaStream.lineEnd();
26329   if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);
26330   range[0] = lambda0$1, range[1] = lambda1;
26331   p0 = null;
26332 }
26333
26334 // Finds the left-right distance between two longitudes.
26335 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
26336 // the distance between ±180° to be 360°.
26337 function angle(lambda0, lambda1) {
26338   return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
26339 }
26340
26341 function rangeCompare(a, b) {
26342   return a[0] - b[0];
26343 }
26344
26345 function rangeContains(range, x) {
26346   return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
26347 }
26348
26349 var bounds = function(feature) {
26350   var i, n, a, b, merged, deltaMax, delta;
26351
26352   phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
26353   ranges = [];
26354   geoStream(feature, boundsStream);
26355
26356   // First, sort ranges by their minimum longitudes.
26357   if (n = ranges.length) {
26358     ranges.sort(rangeCompare);
26359
26360     // Then, merge any ranges that overlap.
26361     for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
26362       b = ranges[i];
26363       if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
26364         if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
26365         if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
26366       } else {
26367         merged.push(a = b);
26368       }
26369     }
26370
26371     // Finally, find the largest gap between the merged ranges.
26372     // The final bounding box will be the inverse of this gap.
26373     for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
26374       b = merged[i];
26375       if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
26376     }
26377   }
26378
26379   ranges = range = null;
26380
26381   return lambda0$1 === Infinity || phi0 === Infinity
26382       ? [[NaN, NaN], [NaN, NaN]]
26383       : [[lambda0$1, phi0], [lambda1, phi1]];
26384 };
26385
26386 var W0;
26387 var W1;
26388 var X0;
26389 var Y0;
26390 var Z0;
26391 var X1;
26392 var Y1;
26393 var Z1;
26394 var X2;
26395 var Y2;
26396 var Z2;
26397 var lambda00$2;
26398 var phi00$2;
26399 var x0;
26400 var y0;
26401 var z0; // previous point
26402
26403 var centroidStream = {
26404   sphere: noop$1,
26405   point: centroidPoint,
26406   lineStart: centroidLineStart,
26407   lineEnd: centroidLineEnd,
26408   polygonStart: function() {
26409     centroidStream.lineStart = centroidRingStart;
26410     centroidStream.lineEnd = centroidRingEnd;
26411   },
26412   polygonEnd: function() {
26413     centroidStream.lineStart = centroidLineStart;
26414     centroidStream.lineEnd = centroidLineEnd;
26415   }
26416 };
26417
26418 // Arithmetic mean of Cartesian vectors.
26419 function centroidPoint(lambda, phi) {
26420   lambda *= radians, phi *= radians;
26421   var cosPhi = cos$1(phi);
26422   centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
26423 }
26424
26425 function centroidPointCartesian(x, y, z) {
26426   ++W0;
26427   X0 += (x - X0) / W0;
26428   Y0 += (y - Y0) / W0;
26429   Z0 += (z - Z0) / W0;
26430 }
26431
26432 function centroidLineStart() {
26433   centroidStream.point = centroidLinePointFirst;
26434 }
26435
26436 function centroidLinePointFirst(lambda, phi) {
26437   lambda *= radians, phi *= radians;
26438   var cosPhi = cos$1(phi);
26439   x0 = cosPhi * cos$1(lambda);
26440   y0 = cosPhi * sin$1(lambda);
26441   z0 = sin$1(phi);
26442   centroidStream.point = centroidLinePoint;
26443   centroidPointCartesian(x0, y0, z0);
26444 }
26445
26446 function centroidLinePoint(lambda, phi) {
26447   lambda *= radians, phi *= radians;
26448   var cosPhi = cos$1(phi),
26449       x = cosPhi * cos$1(lambda),
26450       y = cosPhi * sin$1(lambda),
26451       z = sin$1(phi),
26452       w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
26453   W1 += w;
26454   X1 += w * (x0 + (x0 = x));
26455   Y1 += w * (y0 + (y0 = y));
26456   Z1 += w * (z0 + (z0 = z));
26457   centroidPointCartesian(x0, y0, z0);
26458 }
26459
26460 function centroidLineEnd() {
26461   centroidStream.point = centroidPoint;
26462 }
26463
26464 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
26465 // J. Applied Mechanics 42, 239 (1975).
26466 function centroidRingStart() {
26467   centroidStream.point = centroidRingPointFirst;
26468 }
26469
26470 function centroidRingEnd() {
26471   centroidRingPoint(lambda00$2, phi00$2);
26472   centroidStream.point = centroidPoint;
26473 }
26474
26475 function centroidRingPointFirst(lambda, phi) {
26476   lambda00$2 = lambda, phi00$2 = phi;
26477   lambda *= radians, phi *= radians;
26478   centroidStream.point = centroidRingPoint;
26479   var cosPhi = cos$1(phi);
26480   x0 = cosPhi * cos$1(lambda);
26481   y0 = cosPhi * sin$1(lambda);
26482   z0 = sin$1(phi);
26483   centroidPointCartesian(x0, y0, z0);
26484 }
26485
26486 function centroidRingPoint(lambda, phi) {
26487   lambda *= radians, phi *= radians;
26488   var cosPhi = cos$1(phi),
26489       x = cosPhi * cos$1(lambda),
26490       y = cosPhi * sin$1(lambda),
26491       z = sin$1(phi),
26492       cx = y0 * z - z0 * y,
26493       cy = z0 * x - x0 * z,
26494       cz = x0 * y - y0 * x,
26495       m = sqrt(cx * cx + cy * cy + cz * cz),
26496       w = asin(m), // line weight = angle
26497       v = m && -w / m; // area weight multiplier
26498   X2 += v * cx;
26499   Y2 += v * cy;
26500   Z2 += v * cz;
26501   W1 += w;
26502   X1 += w * (x0 + (x0 = x));
26503   Y1 += w * (y0 + (y0 = y));
26504   Z1 += w * (z0 + (z0 = z));
26505   centroidPointCartesian(x0, y0, z0);
26506 }
26507
26508 var d3GeoCentroid = function(object) {
26509   W0 = W1 =
26510   X0 = Y0 = Z0 =
26511   X1 = Y1 = Z1 =
26512   X2 = Y2 = Z2 = 0;
26513   geoStream(object, centroidStream);
26514
26515   var x = X2,
26516       y = Y2,
26517       z = Z2,
26518       m = x * x + y * y + z * z;
26519
26520   // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
26521   if (m < epsilon2$1) {
26522     x = X1, y = Y1, z = Z1;
26523     // If the feature has zero length, fall back to arithmetic mean of point vectors.
26524     if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;
26525     m = x * x + y * y + z * z;
26526     // If the feature still has an undefined ccentroid, then return.
26527     if (m < epsilon2$1) return [NaN, NaN];
26528   }
26529
26530   return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
26531 };
26532
26533 var constant$7 = function(x) {
26534   return function() {
26535     return x;
26536   };
26537 };
26538
26539 var compose = function(a, b) {
26540
26541   function compose(x, y) {
26542     return x = a(x, y), b(x[0], x[1]);
26543   }
26544
26545   if (a.invert && b.invert) compose.invert = function(x, y) {
26546     return x = b.invert(x, y), x && a.invert(x[0], x[1]);
26547   };
26548
26549   return compose;
26550 };
26551
26552 function rotationIdentity(lambda, phi) {
26553   return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
26554 }
26555
26556 rotationIdentity.invert = rotationIdentity;
26557
26558 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
26559   return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
26560     : rotationLambda(deltaLambda))
26561     : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
26562     : rotationIdentity);
26563 }
26564
26565 function forwardRotationLambda(deltaLambda) {
26566   return function(lambda, phi) {
26567     return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
26568   };
26569 }
26570
26571 function rotationLambda(deltaLambda) {
26572   var rotation = forwardRotationLambda(deltaLambda);
26573   rotation.invert = forwardRotationLambda(-deltaLambda);
26574   return rotation;
26575 }
26576
26577 function rotationPhiGamma(deltaPhi, deltaGamma) {
26578   var cosDeltaPhi = cos$1(deltaPhi),
26579       sinDeltaPhi = sin$1(deltaPhi),
26580       cosDeltaGamma = cos$1(deltaGamma),
26581       sinDeltaGamma = sin$1(deltaGamma);
26582
26583   function rotation(lambda, phi) {
26584     var cosPhi = cos$1(phi),
26585         x = cos$1(lambda) * cosPhi,
26586         y = sin$1(lambda) * cosPhi,
26587         z = sin$1(phi),
26588         k = z * cosDeltaPhi + x * sinDeltaPhi;
26589     return [
26590       atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
26591       asin(k * cosDeltaGamma + y * sinDeltaGamma)
26592     ];
26593   }
26594
26595   rotation.invert = function(lambda, phi) {
26596     var cosPhi = cos$1(phi),
26597         x = cos$1(lambda) * cosPhi,
26598         y = sin$1(lambda) * cosPhi,
26599         z = sin$1(phi),
26600         k = z * cosDeltaGamma - y * sinDeltaGamma;
26601     return [
26602       atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
26603       asin(k * cosDeltaPhi - x * sinDeltaPhi)
26604     ];
26605   };
26606
26607   return rotation;
26608 }
26609
26610 var rotation = function(rotate) {
26611   rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
26612
26613   function forward(coordinates) {
26614     coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
26615     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
26616   }
26617
26618   forward.invert = function(coordinates) {
26619     coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
26620     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
26621   };
26622
26623   return forward;
26624 };
26625
26626 // Generates a circle centered at [0°, 0°], with a given radius and precision.
26627 function circleStream(stream, radius, delta, direction, t0, t1) {
26628   if (!delta) return;
26629   var cosRadius = cos$1(radius),
26630       sinRadius = sin$1(radius),
26631       step = direction * delta;
26632   if (t0 == null) {
26633     t0 = radius + direction * tau$3;
26634     t1 = radius - step / 2;
26635   } else {
26636     t0 = circleRadius(cosRadius, t0);
26637     t1 = circleRadius(cosRadius, t1);
26638     if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;
26639   }
26640   for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
26641     point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
26642     stream.point(point[0], point[1]);
26643   }
26644 }
26645
26646 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
26647 function circleRadius(cosRadius, point) {
26648   point = cartesian(point), point[0] -= cosRadius;
26649   cartesianNormalizeInPlace(point);
26650   var radius = acos(-point[1]);
26651   return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
26652 }
26653
26654 var circle = function() {
26655   var center = constant$7([0, 0]),
26656       radius = constant$7(90),
26657       precision = constant$7(6),
26658       ring,
26659       rotate,
26660       stream = {point: point};
26661
26662   function point(x, y) {
26663     ring.push(x = rotate(x, y));
26664     x[0] *= degrees$1, x[1] *= degrees$1;
26665   }
26666
26667   function circle() {
26668     var c = center.apply(this, arguments),
26669         r = radius.apply(this, arguments) * radians,
26670         p = precision.apply(this, arguments) * radians;
26671     ring = [];
26672     rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
26673     circleStream(stream, r, p, 1);
26674     c = {type: "Polygon", coordinates: [ring]};
26675     ring = rotate = null;
26676     return c;
26677   }
26678
26679   circle.center = function(_) {
26680     return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center;
26681   };
26682
26683   circle.radius = function(_) {
26684     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius;
26685   };
26686
26687   circle.precision = function(_) {
26688     return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision;
26689   };
26690
26691   return circle;
26692 };
26693
26694 var clipBuffer = function() {
26695   var lines = [],
26696       line;
26697   return {
26698     point: function(x, y) {
26699       line.push([x, y]);
26700     },
26701     lineStart: function() {
26702       lines.push(line = []);
26703     },
26704     lineEnd: noop$1,
26705     rejoin: function() {
26706       if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
26707     },
26708     result: function() {
26709       var result = lines;
26710       lines = [];
26711       line = null;
26712       return result;
26713     }
26714   };
26715 };
26716
26717 var clipLine = function(a, b, x0, y0, x1, y1) {
26718   var ax = a[0],
26719       ay = a[1],
26720       bx = b[0],
26721       by = b[1],
26722       t0 = 0,
26723       t1 = 1,
26724       dx = bx - ax,
26725       dy = by - ay,
26726       r;
26727
26728   r = x0 - ax;
26729   if (!dx && r > 0) return;
26730   r /= dx;
26731   if (dx < 0) {
26732     if (r < t0) return;
26733     if (r < t1) t1 = r;
26734   } else if (dx > 0) {
26735     if (r > t1) return;
26736     if (r > t0) t0 = r;
26737   }
26738
26739   r = x1 - ax;
26740   if (!dx && r < 0) return;
26741   r /= dx;
26742   if (dx < 0) {
26743     if (r > t1) return;
26744     if (r > t0) t0 = r;
26745   } else if (dx > 0) {
26746     if (r < t0) return;
26747     if (r < t1) t1 = r;
26748   }
26749
26750   r = y0 - ay;
26751   if (!dy && r > 0) return;
26752   r /= dy;
26753   if (dy < 0) {
26754     if (r < t0) return;
26755     if (r < t1) t1 = r;
26756   } else if (dy > 0) {
26757     if (r > t1) return;
26758     if (r > t0) t0 = r;
26759   }
26760
26761   r = y1 - ay;
26762   if (!dy && r < 0) return;
26763   r /= dy;
26764   if (dy < 0) {
26765     if (r > t1) return;
26766     if (r > t0) t0 = r;
26767   } else if (dy > 0) {
26768     if (r < t0) return;
26769     if (r < t1) t1 = r;
26770   }
26771
26772   if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
26773   if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
26774   return true;
26775 };
26776
26777 var pointEqual = function(a, b) {
26778   return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
26779 };
26780
26781 function Intersection(point, points, other, entry) {
26782   this.x = point;
26783   this.z = points;
26784   this.o = other; // another intersection
26785   this.e = entry; // is an entry?
26786   this.v = false; // visited
26787   this.n = this.p = null; // next & previous
26788 }
26789
26790 // A generalized polygon clipping algorithm: given a polygon that has been cut
26791 // into its visible line segments, and rejoins the segments by interpolating
26792 // along the clip edge.
26793 var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) {
26794   var subject = [],
26795       clip = [],
26796       i,
26797       n;
26798
26799   segments.forEach(function(segment) {
26800     if ((n = segment.length - 1) <= 0) return;
26801     var n, p0 = segment[0], p1 = segment[n], x;
26802
26803     // If the first and last points of a segment are coincident, then treat as a
26804     // closed ring. TODO if all rings are closed, then the winding order of the
26805     // exterior ring should be checked.
26806     if (pointEqual(p0, p1)) {
26807       stream.lineStart();
26808       for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
26809       stream.lineEnd();
26810       return;
26811     }
26812
26813     subject.push(x = new Intersection(p0, segment, null, true));
26814     clip.push(x.o = new Intersection(p0, null, x, false));
26815     subject.push(x = new Intersection(p1, segment, null, false));
26816     clip.push(x.o = new Intersection(p1, null, x, true));
26817   });
26818
26819   if (!subject.length) return;
26820
26821   clip.sort(compareIntersection);
26822   link$1(subject);
26823   link$1(clip);
26824
26825   for (i = 0, n = clip.length; i < n; ++i) {
26826     clip[i].e = startInside = !startInside;
26827   }
26828
26829   var start = subject[0],
26830       points,
26831       point;
26832
26833   while (1) {
26834     // Find first unvisited intersection.
26835     var current = start,
26836         isSubject = true;
26837     while (current.v) if ((current = current.n) === start) return;
26838     points = current.z;
26839     stream.lineStart();
26840     do {
26841       current.v = current.o.v = true;
26842       if (current.e) {
26843         if (isSubject) {
26844           for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
26845         } else {
26846           interpolate(current.x, current.n.x, 1, stream);
26847         }
26848         current = current.n;
26849       } else {
26850         if (isSubject) {
26851           points = current.p.z;
26852           for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
26853         } else {
26854           interpolate(current.x, current.p.x, -1, stream);
26855         }
26856         current = current.p;
26857       }
26858       current = current.o;
26859       points = current.z;
26860       isSubject = !isSubject;
26861     } while (!current.v);
26862     stream.lineEnd();
26863   }
26864 };
26865
26866 function link$1(array) {
26867   if (!(n = array.length)) return;
26868   var n,
26869       i = 0,
26870       a = array[0],
26871       b;
26872   while (++i < n) {
26873     a.n = b = array[i];
26874     b.p = a;
26875     a = b;
26876   }
26877   a.n = b = array[0];
26878   b.p = a;
26879 }
26880
26881 var clipMax = 1e9;
26882 var clipMin = -clipMax;
26883
26884 // TODO Use d3-polygon’s polygonContains here for the ring check?
26885 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
26886
26887 function clipExtent(x0, y0, x1, y1) {
26888
26889   function visible(x, y) {
26890     return x0 <= x && x <= x1 && y0 <= y && y <= y1;
26891   }
26892
26893   function interpolate(from, to, direction, stream) {
26894     var a = 0, a1 = 0;
26895     if (from == null
26896         || (a = corner(from, direction)) !== (a1 = corner(to, direction))
26897         || comparePoint(from, to) < 0 ^ direction > 0) {
26898       do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
26899       while ((a = (a + direction + 4) % 4) !== a1);
26900     } else {
26901       stream.point(to[0], to[1]);
26902     }
26903   }
26904
26905   function corner(p, direction) {
26906     return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
26907         : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
26908         : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
26909         : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
26910   }
26911
26912   function compareIntersection(a, b) {
26913     return comparePoint(a.x, b.x);
26914   }
26915
26916   function comparePoint(a, b) {
26917     var ca = corner(a, 1),
26918         cb = corner(b, 1);
26919     return ca !== cb ? ca - cb
26920         : ca === 0 ? b[1] - a[1]
26921         : ca === 1 ? a[0] - b[0]
26922         : ca === 2 ? a[1] - b[1]
26923         : b[0] - a[0];
26924   }
26925
26926   return function(stream) {
26927     var activeStream = stream,
26928         bufferStream = clipBuffer(),
26929         segments,
26930         polygon,
26931         ring,
26932         x__, y__, v__, // first point
26933         x_, y_, v_, // previous point
26934         first,
26935         clean;
26936
26937     var clipStream = {
26938       point: point,
26939       lineStart: lineStart,
26940       lineEnd: lineEnd,
26941       polygonStart: polygonStart,
26942       polygonEnd: polygonEnd
26943     };
26944
26945     function point(x, y) {
26946       if (visible(x, y)) activeStream.point(x, y);
26947     }
26948
26949     function polygonInside() {
26950       var winding = 0;
26951
26952       for (var i = 0, n = polygon.length; i < n; ++i) {
26953         for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
26954           a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
26955           if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
26956           else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
26957         }
26958       }
26959
26960       return winding;
26961     }
26962
26963     // Buffer geometry within a polygon and then clip it en masse.
26964     function polygonStart() {
26965       activeStream = bufferStream, segments = [], polygon = [], clean = true;
26966     }
26967
26968     function polygonEnd() {
26969       var startInside = polygonInside(),
26970           cleanInside = clean && startInside,
26971           visible = (segments = merge(segments)).length;
26972       if (cleanInside || visible) {
26973         stream.polygonStart();
26974         if (cleanInside) {
26975           stream.lineStart();
26976           interpolate(null, null, 1, stream);
26977           stream.lineEnd();
26978         }
26979         if (visible) {
26980           clipPolygon(segments, compareIntersection, startInside, interpolate, stream);
26981         }
26982         stream.polygonEnd();
26983       }
26984       activeStream = stream, segments = polygon = ring = null;
26985     }
26986
26987     function lineStart() {
26988       clipStream.point = linePoint;
26989       if (polygon) polygon.push(ring = []);
26990       first = true;
26991       v_ = false;
26992       x_ = y_ = NaN;
26993     }
26994
26995     // TODO rather than special-case polygons, simply handle them separately.
26996     // Ideally, coincident intersection points should be jittered to avoid
26997     // clipping issues.
26998     function lineEnd() {
26999       if (segments) {
27000         linePoint(x__, y__);
27001         if (v__ && v_) bufferStream.rejoin();
27002         segments.push(bufferStream.result());
27003       }
27004       clipStream.point = point;
27005       if (v_) activeStream.lineEnd();
27006     }
27007
27008     function linePoint(x, y) {
27009       var v = visible(x, y);
27010       if (polygon) ring.push([x, y]);
27011       if (first) {
27012         x__ = x, y__ = y, v__ = v;
27013         first = false;
27014         if (v) {
27015           activeStream.lineStart();
27016           activeStream.point(x, y);
27017         }
27018       } else {
27019         if (v && v_) activeStream.point(x, y);
27020         else {
27021           var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
27022               b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
27023           if (clipLine(a, b, x0, y0, x1, y1)) {
27024             if (!v_) {
27025               activeStream.lineStart();
27026               activeStream.point(a[0], a[1]);
27027             }
27028             activeStream.point(b[0], b[1]);
27029             if (!v) activeStream.lineEnd();
27030             clean = false;
27031           } else if (v) {
27032             activeStream.lineStart();
27033             activeStream.point(x, y);
27034             clean = false;
27035           }
27036         }
27037       }
27038       x_ = x, y_ = y, v_ = v;
27039     }
27040
27041     return clipStream;
27042   };
27043 }
27044
27045 var extent$1 = function() {
27046   var x0 = 0,
27047       y0 = 0,
27048       x1 = 960,
27049       y1 = 500,
27050       cache,
27051       cacheStream,
27052       clip;
27053
27054   return clip = {
27055     stream: function(stream) {
27056       return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream);
27057     },
27058     extent: function(_) {
27059       return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
27060     }
27061   };
27062 };
27063
27064 var sum$1 = adder();
27065
27066 var polygonContains = function(polygon, point) {
27067   var lambda = point[0],
27068       phi = point[1],
27069       normal = [sin$1(lambda), -cos$1(lambda), 0],
27070       angle = 0,
27071       winding = 0;
27072
27073   sum$1.reset();
27074
27075   for (var i = 0, n = polygon.length; i < n; ++i) {
27076     if (!(m = (ring = polygon[i]).length)) continue;
27077     var ring,
27078         m,
27079         point0 = ring[m - 1],
27080         lambda0 = point0[0],
27081         phi0 = point0[1] / 2 + quarterPi,
27082         sinPhi0 = sin$1(phi0),
27083         cosPhi0 = cos$1(phi0);
27084
27085     for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
27086       var point1 = ring[j],
27087           lambda1 = point1[0],
27088           phi1 = point1[1] / 2 + quarterPi,
27089           sinPhi1 = sin$1(phi1),
27090           cosPhi1 = cos$1(phi1),
27091           delta = lambda1 - lambda0,
27092           sign$$1 = delta >= 0 ? 1 : -1,
27093           absDelta = sign$$1 * delta,
27094           antimeridian = absDelta > pi$3,
27095           k = sinPhi0 * sinPhi1;
27096
27097       sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
27098       angle += antimeridian ? delta + sign$$1 * tau$3 : delta;
27099
27100       // Are the longitudes either side of the point’s meridian (lambda),
27101       // and are the latitudes smaller than the parallel (phi)?
27102       if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
27103         var arc = cartesianCross(cartesian(point0), cartesian(point1));
27104         cartesianNormalizeInPlace(arc);
27105         var intersection = cartesianCross(normal, arc);
27106         cartesianNormalizeInPlace(intersection);
27107         var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
27108         if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
27109           winding += antimeridian ^ delta >= 0 ? 1 : -1;
27110         }
27111       }
27112     }
27113   }
27114
27115   // First, determine whether the South pole is inside or outside:
27116   //
27117   // It is inside if:
27118   // * the polygon winds around it in a clockwise direction.
27119   // * the polygon does not (cumulatively) wind around it, but has a negative
27120   //   (counter-clockwise) area.
27121   //
27122   // Second, count the (signed) number of times a segment crosses a lambda
27123   // from the point to the South pole.  If it is zero, then the point is the
27124   // same side as the South pole.
27125
27126   return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);
27127 };
27128
27129 var lengthSum = adder();
27130 var lambda0$2;
27131 var sinPhi0$1;
27132 var cosPhi0$1;
27133
27134 var lengthStream = {
27135   sphere: noop$1,
27136   point: noop$1,
27137   lineStart: lengthLineStart,
27138   lineEnd: noop$1,
27139   polygonStart: noop$1,
27140   polygonEnd: noop$1
27141 };
27142
27143 function lengthLineStart() {
27144   lengthStream.point = lengthPointFirst;
27145   lengthStream.lineEnd = lengthLineEnd;
27146 }
27147
27148 function lengthLineEnd() {
27149   lengthStream.point = lengthStream.lineEnd = noop$1;
27150 }
27151
27152 function lengthPointFirst(lambda, phi) {
27153   lambda *= radians, phi *= radians;
27154   lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
27155   lengthStream.point = lengthPoint;
27156 }
27157
27158 function lengthPoint(lambda, phi) {
27159   lambda *= radians, phi *= radians;
27160   var sinPhi = sin$1(phi),
27161       cosPhi = cos$1(phi),
27162       delta = abs(lambda - lambda0$2),
27163       cosDelta = cos$1(delta),
27164       sinDelta = sin$1(delta),
27165       x = cosPhi * sinDelta,
27166       y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
27167       z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
27168   lengthSum.add(atan2(sqrt(x * x + y * y), z));
27169   lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
27170 }
27171
27172 var d3GeoLength = function(object) {
27173   lengthSum.reset();
27174   geoStream(object, lengthStream);
27175   return +lengthSum;
27176 };
27177
27178 var coordinates = [null, null];
27179 var object$1 = {type: "LineString", coordinates: coordinates};
27180
27181 var distance = function(a, b) {
27182   coordinates[0] = a;
27183   coordinates[1] = b;
27184   return d3GeoLength(object$1);
27185 };
27186
27187 var containsObjectType = {
27188   Feature: function(object, point) {
27189     return containsGeometry(object.geometry, point);
27190   },
27191   FeatureCollection: function(object, point) {
27192     var features = object.features, i = -1, n = features.length;
27193     while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
27194     return false;
27195   }
27196 };
27197
27198 var containsGeometryType = {
27199   Sphere: function() {
27200     return true;
27201   },
27202   Point: function(object, point) {
27203     return containsPoint(object.coordinates, point);
27204   },
27205   MultiPoint: function(object, point) {
27206     var coordinates = object.coordinates, i = -1, n = coordinates.length;
27207     while (++i < n) if (containsPoint(coordinates[i], point)) return true;
27208     return false;
27209   },
27210   LineString: function(object, point) {
27211     return containsLine(object.coordinates, point);
27212   },
27213   MultiLineString: function(object, point) {
27214     var coordinates = object.coordinates, i = -1, n = coordinates.length;
27215     while (++i < n) if (containsLine(coordinates[i], point)) return true;
27216     return false;
27217   },
27218   Polygon: function(object, point) {
27219     return containsPolygon(object.coordinates, point);
27220   },
27221   MultiPolygon: function(object, point) {
27222     var coordinates = object.coordinates, i = -1, n = coordinates.length;
27223     while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
27224     return false;
27225   },
27226   GeometryCollection: function(object, point) {
27227     var geometries = object.geometries, i = -1, n = geometries.length;
27228     while (++i < n) if (containsGeometry(geometries[i], point)) return true;
27229     return false;
27230   }
27231 };
27232
27233 function containsGeometry(geometry, point) {
27234   return geometry && containsGeometryType.hasOwnProperty(geometry.type)
27235       ? containsGeometryType[geometry.type](geometry, point)
27236       : false;
27237 }
27238
27239 function containsPoint(coordinates, point) {
27240   return distance(coordinates, point) === 0;
27241 }
27242
27243 function containsLine(coordinates, point) {
27244   var ab = distance(coordinates[0], coordinates[1]),
27245       ao = distance(coordinates[0], point),
27246       ob = distance(point, coordinates[1]);
27247   return ao + ob <= ab + epsilon$2;
27248 }
27249
27250 function containsPolygon(coordinates, point) {
27251   return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
27252 }
27253
27254 function ringRadians(ring) {
27255   return ring = ring.map(pointRadians), ring.pop(), ring;
27256 }
27257
27258 function pointRadians(point) {
27259   return [point[0] * radians, point[1] * radians];
27260 }
27261
27262 var contains = function(object, point) {
27263   return (object && containsObjectType.hasOwnProperty(object.type)
27264       ? containsObjectType[object.type]
27265       : containsGeometry)(object, point);
27266 };
27267
27268 function graticuleX(y0, y1, dy) {
27269   var y = sequence(y0, y1 - epsilon$2, dy).concat(y1);
27270   return function(x) { return y.map(function(y) { return [x, y]; }); };
27271 }
27272
27273 function graticuleY(x0, x1, dx) {
27274   var x = sequence(x0, x1 - epsilon$2, dx).concat(x1);
27275   return function(y) { return x.map(function(x) { return [x, y]; }); };
27276 }
27277
27278 function graticule() {
27279   var x1, x0, X1, X0,
27280       y1, y0, Y1, Y0,
27281       dx = 10, dy = dx, DX = 90, DY = 360,
27282       x, y, X, Y,
27283       precision = 2.5;
27284
27285   function graticule() {
27286     return {type: "MultiLineString", coordinates: lines()};
27287   }
27288
27289   function lines() {
27290     return sequence(ceil(X0 / DX) * DX, X1, DX).map(X)
27291         .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
27292         .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))
27293         .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));
27294   }
27295
27296   graticule.lines = function() {
27297     return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
27298   };
27299
27300   graticule.outline = function() {
27301     return {
27302       type: "Polygon",
27303       coordinates: [
27304         X(X0).concat(
27305         Y(Y1).slice(1),
27306         X(X1).reverse().slice(1),
27307         Y(Y0).reverse().slice(1))
27308       ]
27309     };
27310   };
27311
27312   graticule.extent = function(_) {
27313     if (!arguments.length) return graticule.extentMinor();
27314     return graticule.extentMajor(_).extentMinor(_);
27315   };
27316
27317   graticule.extentMajor = function(_) {
27318     if (!arguments.length) return [[X0, Y0], [X1, Y1]];
27319     X0 = +_[0][0], X1 = +_[1][0];
27320     Y0 = +_[0][1], Y1 = +_[1][1];
27321     if (X0 > X1) _ = X0, X0 = X1, X1 = _;
27322     if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
27323     return graticule.precision(precision);
27324   };
27325
27326   graticule.extentMinor = function(_) {
27327     if (!arguments.length) return [[x0, y0], [x1, y1]];
27328     x0 = +_[0][0], x1 = +_[1][0];
27329     y0 = +_[0][1], y1 = +_[1][1];
27330     if (x0 > x1) _ = x0, x0 = x1, x1 = _;
27331     if (y0 > y1) _ = y0, y0 = y1, y1 = _;
27332     return graticule.precision(precision);
27333   };
27334
27335   graticule.step = function(_) {
27336     if (!arguments.length) return graticule.stepMinor();
27337     return graticule.stepMajor(_).stepMinor(_);
27338   };
27339
27340   graticule.stepMajor = function(_) {
27341     if (!arguments.length) return [DX, DY];
27342     DX = +_[0], DY = +_[1];
27343     return graticule;
27344   };
27345
27346   graticule.stepMinor = function(_) {
27347     if (!arguments.length) return [dx, dy];
27348     dx = +_[0], dy = +_[1];
27349     return graticule;
27350   };
27351
27352   graticule.precision = function(_) {
27353     if (!arguments.length) return precision;
27354     precision = +_;
27355     x = graticuleX(y0, y1, 90);
27356     y = graticuleY(x0, x1, precision);
27357     X = graticuleX(Y0, Y1, 90);
27358     Y = graticuleY(X0, X1, precision);
27359     return graticule;
27360   };
27361
27362   return graticule
27363       .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
27364       .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
27365 }
27366
27367 function graticule10() {
27368   return graticule()();
27369 }
27370
27371 var interpolate$1 = function(a, b) {
27372   var x0 = a[0] * radians,
27373       y0 = a[1] * radians,
27374       x1 = b[0] * radians,
27375       y1 = b[1] * radians,
27376       cy0 = cos$1(y0),
27377       sy0 = sin$1(y0),
27378       cy1 = cos$1(y1),
27379       sy1 = sin$1(y1),
27380       kx0 = cy0 * cos$1(x0),
27381       ky0 = cy0 * sin$1(x0),
27382       kx1 = cy1 * cos$1(x1),
27383       ky1 = cy1 * sin$1(x1),
27384       d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
27385       k = sin$1(d);
27386
27387   var interpolate = d ? function(t) {
27388     var B = sin$1(t *= d) / k,
27389         A = sin$1(d - t) / k,
27390         x = A * kx0 + B * kx1,
27391         y = A * ky0 + B * ky1,
27392         z = A * sy0 + B * sy1;
27393     return [
27394       atan2(y, x) * degrees$1,
27395       atan2(z, sqrt(x * x + y * y)) * degrees$1
27396     ];
27397   } : function() {
27398     return [x0 * degrees$1, y0 * degrees$1];
27399   };
27400
27401   interpolate.distance = d;
27402
27403   return interpolate;
27404 };
27405
27406 var identity$4 = function(x) {
27407   return x;
27408 };
27409
27410 var areaSum$1 = adder();
27411 var areaRingSum$1 = adder();
27412 var x00;
27413 var y00;
27414 var x0$1;
27415 var y0$1;
27416
27417 var areaStream$1 = {
27418   point: noop$1,
27419   lineStart: noop$1,
27420   lineEnd: noop$1,
27421   polygonStart: function() {
27422     areaStream$1.lineStart = areaRingStart$1;
27423     areaStream$1.lineEnd = areaRingEnd$1;
27424   },
27425   polygonEnd: function() {
27426     areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;
27427     areaSum$1.add(abs(areaRingSum$1));
27428     areaRingSum$1.reset();
27429   },
27430   result: function() {
27431     var area = areaSum$1 / 2;
27432     areaSum$1.reset();
27433     return area;
27434   }
27435 };
27436
27437 function areaRingStart$1() {
27438   areaStream$1.point = areaPointFirst$1;
27439 }
27440
27441 function areaPointFirst$1(x, y) {
27442   areaStream$1.point = areaPoint$1;
27443   x00 = x0$1 = x, y00 = y0$1 = y;
27444 }
27445
27446 function areaPoint$1(x, y) {
27447   areaRingSum$1.add(y0$1 * x - x0$1 * y);
27448   x0$1 = x, y0$1 = y;
27449 }
27450
27451 function areaRingEnd$1() {
27452   areaPoint$1(x00, y00);
27453 }
27454
27455 var x0$2 = Infinity;
27456 var y0$2 = x0$2;
27457 var x1 = -x0$2;
27458 var y1 = x1;
27459
27460 var boundsStream$1 = {
27461   point: boundsPoint$1,
27462   lineStart: noop$1,
27463   lineEnd: noop$1,
27464   polygonStart: noop$1,
27465   polygonEnd: noop$1,
27466   result: function() {
27467     var bounds = [[x0$2, y0$2], [x1, y1]];
27468     x1 = y1 = -(y0$2 = x0$2 = Infinity);
27469     return bounds;
27470   }
27471 };
27472
27473 function boundsPoint$1(x, y) {
27474   if (x < x0$2) x0$2 = x;
27475   if (x > x1) x1 = x;
27476   if (y < y0$2) y0$2 = y;
27477   if (y > y1) y1 = y;
27478 }
27479
27480 // TODO Enforce positive area for exterior, negative area for interior?
27481
27482 var X0$1 = 0;
27483 var Y0$1 = 0;
27484 var Z0$1 = 0;
27485 var X1$1 = 0;
27486 var Y1$1 = 0;
27487 var Z1$1 = 0;
27488 var X2$1 = 0;
27489 var Y2$1 = 0;
27490 var Z2$1 = 0;
27491 var x00$1;
27492 var y00$1;
27493 var x0$3;
27494 var y0$3;
27495
27496 var centroidStream$1 = {
27497   point: centroidPoint$1,
27498   lineStart: centroidLineStart$1,
27499   lineEnd: centroidLineEnd$1,
27500   polygonStart: function() {
27501     centroidStream$1.lineStart = centroidRingStart$1;
27502     centroidStream$1.lineEnd = centroidRingEnd$1;
27503   },
27504   polygonEnd: function() {
27505     centroidStream$1.point = centroidPoint$1;
27506     centroidStream$1.lineStart = centroidLineStart$1;
27507     centroidStream$1.lineEnd = centroidLineEnd$1;
27508   },
27509   result: function() {
27510     var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
27511         : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
27512         : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
27513         : [NaN, NaN];
27514     X0$1 = Y0$1 = Z0$1 =
27515     X1$1 = Y1$1 = Z1$1 =
27516     X2$1 = Y2$1 = Z2$1 = 0;
27517     return centroid;
27518   }
27519 };
27520
27521 function centroidPoint$1(x, y) {
27522   X0$1 += x;
27523   Y0$1 += y;
27524   ++Z0$1;
27525 }
27526
27527 function centroidLineStart$1() {
27528   centroidStream$1.point = centroidPointFirstLine;
27529 }
27530
27531 function centroidPointFirstLine(x, y) {
27532   centroidStream$1.point = centroidPointLine;
27533   centroidPoint$1(x0$3 = x, y0$3 = y);
27534 }
27535
27536 function centroidPointLine(x, y) {
27537   var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
27538   X1$1 += z * (x0$3 + x) / 2;
27539   Y1$1 += z * (y0$3 + y) / 2;
27540   Z1$1 += z;
27541   centroidPoint$1(x0$3 = x, y0$3 = y);
27542 }
27543
27544 function centroidLineEnd$1() {
27545   centroidStream$1.point = centroidPoint$1;
27546 }
27547
27548 function centroidRingStart$1() {
27549   centroidStream$1.point = centroidPointFirstRing;
27550 }
27551
27552 function centroidRingEnd$1() {
27553   centroidPointRing(x00$1, y00$1);
27554 }
27555
27556 function centroidPointFirstRing(x, y) {
27557   centroidStream$1.point = centroidPointRing;
27558   centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
27559 }
27560
27561 function centroidPointRing(x, y) {
27562   var dx = x - x0$3,
27563       dy = y - y0$3,
27564       z = sqrt(dx * dx + dy * dy);
27565
27566   X1$1 += z * (x0$3 + x) / 2;
27567   Y1$1 += z * (y0$3 + y) / 2;
27568   Z1$1 += z;
27569
27570   z = y0$3 * x - x0$3 * y;
27571   X2$1 += z * (x0$3 + x);
27572   Y2$1 += z * (y0$3 + y);
27573   Z2$1 += z * 3;
27574   centroidPoint$1(x0$3 = x, y0$3 = y);
27575 }
27576
27577 function PathContext(context) {
27578   this._context = context;
27579 }
27580
27581 PathContext.prototype = {
27582   _radius: 4.5,
27583   pointRadius: function(_) {
27584     return this._radius = _, this;
27585   },
27586   polygonStart: function() {
27587     this._line = 0;
27588   },
27589   polygonEnd: function() {
27590     this._line = NaN;
27591   },
27592   lineStart: function() {
27593     this._point = 0;
27594   },
27595   lineEnd: function() {
27596     if (this._line === 0) this._context.closePath();
27597     this._point = NaN;
27598   },
27599   point: function(x, y) {
27600     switch (this._point) {
27601       case 0: {
27602         this._context.moveTo(x, y);
27603         this._point = 1;
27604         break;
27605       }
27606       case 1: {
27607         this._context.lineTo(x, y);
27608         break;
27609       }
27610       default: {
27611         this._context.moveTo(x + this._radius, y);
27612         this._context.arc(x, y, this._radius, 0, tau$3);
27613         break;
27614       }
27615     }
27616   },
27617   result: noop$1
27618 };
27619
27620 var lengthSum$1 = adder();
27621 var lengthRing;
27622 var x00$2;
27623 var y00$2;
27624 var x0$4;
27625 var y0$4;
27626
27627 var lengthStream$1 = {
27628   point: noop$1,
27629   lineStart: function() {
27630     lengthStream$1.point = lengthPointFirst$1;
27631   },
27632   lineEnd: function() {
27633     if (lengthRing) lengthPoint$1(x00$2, y00$2);
27634     lengthStream$1.point = noop$1;
27635   },
27636   polygonStart: function() {
27637     lengthRing = true;
27638   },
27639   polygonEnd: function() {
27640     lengthRing = null;
27641   },
27642   result: function() {
27643     var length = +lengthSum$1;
27644     lengthSum$1.reset();
27645     return length;
27646   }
27647 };
27648
27649 function lengthPointFirst$1(x, y) {
27650   lengthStream$1.point = lengthPoint$1;
27651   x00$2 = x0$4 = x, y00$2 = y0$4 = y;
27652 }
27653
27654 function lengthPoint$1(x, y) {
27655   x0$4 -= x, y0$4 -= y;
27656   lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
27657   x0$4 = x, y0$4 = y;
27658 }
27659
27660 function PathString() {
27661   this._string = [];
27662 }
27663
27664 PathString.prototype = {
27665   _radius: 4.5,
27666   _circle: circle$1(4.5),
27667   pointRadius: function(_) {
27668     if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;
27669     return this;
27670   },
27671   polygonStart: function() {
27672     this._line = 0;
27673   },
27674   polygonEnd: function() {
27675     this._line = NaN;
27676   },
27677   lineStart: function() {
27678     this._point = 0;
27679   },
27680   lineEnd: function() {
27681     if (this._line === 0) this._string.push("Z");
27682     this._point = NaN;
27683   },
27684   point: function(x, y) {
27685     switch (this._point) {
27686       case 0: {
27687         this._string.push("M", x, ",", y);
27688         this._point = 1;
27689         break;
27690       }
27691       case 1: {
27692         this._string.push("L", x, ",", y);
27693         break;
27694       }
27695       default: {
27696         if (this._circle == null) this._circle = circle$1(this._radius);
27697         this._string.push("M", x, ",", y, this._circle);
27698         break;
27699       }
27700     }
27701   },
27702   result: function() {
27703     if (this._string.length) {
27704       var result = this._string.join("");
27705       this._string = [];
27706       return result;
27707     } else {
27708       return null;
27709     }
27710   }
27711 };
27712
27713 function circle$1(radius) {
27714   return "m0," + radius
27715       + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
27716       + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
27717       + "z";
27718 }
27719
27720 var index$4 = function(projection, context) {
27721   var pointRadius = 4.5,
27722       projectionStream,
27723       contextStream;
27724
27725   function path(object) {
27726     if (object) {
27727       if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
27728       geoStream(object, projectionStream(contextStream));
27729     }
27730     return contextStream.result();
27731   }
27732
27733   path.area = function(object) {
27734     geoStream(object, projectionStream(areaStream$1));
27735     return areaStream$1.result();
27736   };
27737
27738   path.measure = function(object) {
27739     geoStream(object, projectionStream(lengthStream$1));
27740     return lengthStream$1.result();
27741   };
27742
27743   path.bounds = function(object) {
27744     geoStream(object, projectionStream(boundsStream$1));
27745     return boundsStream$1.result();
27746   };
27747
27748   path.centroid = function(object) {
27749     geoStream(object, projectionStream(centroidStream$1));
27750     return centroidStream$1.result();
27751   };
27752
27753   path.projection = function(_) {
27754     return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;
27755   };
27756
27757   path.context = function(_) {
27758     if (!arguments.length) return context;
27759     contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
27760     if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
27761     return path;
27762   };
27763
27764   path.pointRadius = function(_) {
27765     if (!arguments.length) return pointRadius;
27766     pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
27767     return path;
27768   };
27769
27770   return path.projection(projection).context(context);
27771 };
27772
27773 var clip = function(pointVisible, clipLine, interpolate, start) {
27774   return function(rotate, sink) {
27775     var line = clipLine(sink),
27776         rotatedStart = rotate.invert(start[0], start[1]),
27777         ringBuffer = clipBuffer(),
27778         ringSink = clipLine(ringBuffer),
27779         polygonStarted = false,
27780         polygon,
27781         segments,
27782         ring;
27783
27784     var clip = {
27785       point: point,
27786       lineStart: lineStart,
27787       lineEnd: lineEnd,
27788       polygonStart: function() {
27789         clip.point = pointRing;
27790         clip.lineStart = ringStart;
27791         clip.lineEnd = ringEnd;
27792         segments = [];
27793         polygon = [];
27794       },
27795       polygonEnd: function() {
27796         clip.point = point;
27797         clip.lineStart = lineStart;
27798         clip.lineEnd = lineEnd;
27799         segments = merge(segments);
27800         var startInside = polygonContains(polygon, rotatedStart);
27801         if (segments.length) {
27802           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
27803           clipPolygon(segments, compareIntersection, startInside, interpolate, sink);
27804         } else if (startInside) {
27805           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
27806           sink.lineStart();
27807           interpolate(null, null, 1, sink);
27808           sink.lineEnd();
27809         }
27810         if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
27811         segments = polygon = null;
27812       },
27813       sphere: function() {
27814         sink.polygonStart();
27815         sink.lineStart();
27816         interpolate(null, null, 1, sink);
27817         sink.lineEnd();
27818         sink.polygonEnd();
27819       }
27820     };
27821
27822     function point(lambda, phi) {
27823       var point = rotate(lambda, phi);
27824       if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);
27825     }
27826
27827     function pointLine(lambda, phi) {
27828       var point = rotate(lambda, phi);
27829       line.point(point[0], point[1]);
27830     }
27831
27832     function lineStart() {
27833       clip.point = pointLine;
27834       line.lineStart();
27835     }
27836
27837     function lineEnd() {
27838       clip.point = point;
27839       line.lineEnd();
27840     }
27841
27842     function pointRing(lambda, phi) {
27843       ring.push([lambda, phi]);
27844       var point = rotate(lambda, phi);
27845       ringSink.point(point[0], point[1]);
27846     }
27847
27848     function ringStart() {
27849       ringSink.lineStart();
27850       ring = [];
27851     }
27852
27853     function ringEnd() {
27854       pointRing(ring[0][0], ring[0][1]);
27855       ringSink.lineEnd();
27856
27857       var clean = ringSink.clean(),
27858           ringSegments = ringBuffer.result(),
27859           i, n = ringSegments.length, m,
27860           segment,
27861           point;
27862
27863       ring.pop();
27864       polygon.push(ring);
27865       ring = null;
27866
27867       if (!n) return;
27868
27869       // No intersections.
27870       if (clean & 1) {
27871         segment = ringSegments[0];
27872         if ((m = segment.length - 1) > 0) {
27873           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
27874           sink.lineStart();
27875           for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
27876           sink.lineEnd();
27877         }
27878         return;
27879       }
27880
27881       // Rejoin connected segments.
27882       // TODO reuse ringBuffer.rejoin()?
27883       if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
27884
27885       segments.push(ringSegments.filter(validSegment));
27886     }
27887
27888     return clip;
27889   };
27890 };
27891
27892 function validSegment(segment) {
27893   return segment.length > 1;
27894 }
27895
27896 // Intersections are sorted along the clip edge. For both antimeridian cutting
27897 // and circle clipping, the same comparison is used.
27898 function compareIntersection(a, b) {
27899   return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])
27900        - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);
27901 }
27902
27903 var clipAntimeridian = clip(
27904   function() { return true; },
27905   clipAntimeridianLine,
27906   clipAntimeridianInterpolate,
27907   [-pi$3, -halfPi$2]
27908 );
27909
27910 // Takes a line and cuts into visible segments. Return values: 0 - there were
27911 // intersections or the line was empty; 1 - no intersections; 2 - there were
27912 // intersections, and the first and last segments should be rejoined.
27913 function clipAntimeridianLine(stream) {
27914   var lambda0 = NaN,
27915       phi0 = NaN,
27916       sign0 = NaN,
27917       clean; // no intersections
27918
27919   return {
27920     lineStart: function() {
27921       stream.lineStart();
27922       clean = 1;
27923     },
27924     point: function(lambda1, phi1) {
27925       var sign1 = lambda1 > 0 ? pi$3 : -pi$3,
27926           delta = abs(lambda1 - lambda0);
27927       if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
27928         stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);
27929         stream.point(sign0, phi0);
27930         stream.lineEnd();
27931         stream.lineStart();
27932         stream.point(sign1, phi0);
27933         stream.point(lambda1, phi0);
27934         clean = 0;
27935       } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian
27936         if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies
27937         if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;
27938         phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
27939         stream.point(sign0, phi0);
27940         stream.lineEnd();
27941         stream.lineStart();
27942         stream.point(sign1, phi0);
27943         clean = 0;
27944       }
27945       stream.point(lambda0 = lambda1, phi0 = phi1);
27946       sign0 = sign1;
27947     },
27948     lineEnd: function() {
27949       stream.lineEnd();
27950       lambda0 = phi0 = NaN;
27951     },
27952     clean: function() {
27953       return 2 - clean; // if intersections, rejoin first and last segments
27954     }
27955   };
27956 }
27957
27958 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
27959   var cosPhi0,
27960       cosPhi1,
27961       sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
27962   return abs(sinLambda0Lambda1) > epsilon$2
27963       ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
27964           - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
27965           / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
27966       : (phi0 + phi1) / 2;
27967 }
27968
27969 function clipAntimeridianInterpolate(from, to, direction, stream) {
27970   var phi;
27971   if (from == null) {
27972     phi = direction * halfPi$2;
27973     stream.point(-pi$3, phi);
27974     stream.point(0, phi);
27975     stream.point(pi$3, phi);
27976     stream.point(pi$3, 0);
27977     stream.point(pi$3, -phi);
27978     stream.point(0, -phi);
27979     stream.point(-pi$3, -phi);
27980     stream.point(-pi$3, 0);
27981     stream.point(-pi$3, phi);
27982   } else if (abs(from[0] - to[0]) > epsilon$2) {
27983     var lambda = from[0] < to[0] ? pi$3 : -pi$3;
27984     phi = direction * lambda / 2;
27985     stream.point(-lambda, phi);
27986     stream.point(0, phi);
27987     stream.point(lambda, phi);
27988   } else {
27989     stream.point(to[0], to[1]);
27990   }
27991 }
27992
27993 var clipCircle = function(radius, delta) {
27994   var cr = cos$1(radius),
27995       smallRadius = cr > 0,
27996       notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case
27997
27998   function interpolate(from, to, direction, stream) {
27999     circleStream(stream, radius, delta, direction, from, to);
28000   }
28001
28002   function visible(lambda, phi) {
28003     return cos$1(lambda) * cos$1(phi) > cr;
28004   }
28005
28006   // Takes a line and cuts into visible segments. Return values used for polygon
28007   // clipping: 0 - there were intersections or the line was empty; 1 - no
28008   // intersections 2 - there were intersections, and the first and last segments
28009   // should be rejoined.
28010   function clipLine(stream) {
28011     var point0, // previous point
28012         c0, // code for previous point
28013         v0, // visibility of previous point
28014         v00, // visibility of first point
28015         clean; // no intersections
28016     return {
28017       lineStart: function() {
28018         v00 = v0 = false;
28019         clean = 1;
28020       },
28021       point: function(lambda, phi) {
28022         var point1 = [lambda, phi],
28023             point2,
28024             v = visible(lambda, phi),
28025             c = smallRadius
28026               ? v ? 0 : code(lambda, phi)
28027               : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
28028         if (!point0 && (v00 = v0 = v)) stream.lineStart();
28029         // Handle degeneracies.
28030         // TODO ignore if not clipping polygons.
28031         if (v !== v0) {
28032           point2 = intersect(point0, point1);
28033           if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {
28034             point1[0] += epsilon$2;
28035             point1[1] += epsilon$2;
28036             v = visible(point1[0], point1[1]);
28037           }
28038         }
28039         if (v !== v0) {
28040           clean = 0;
28041           if (v) {
28042             // outside going in
28043             stream.lineStart();
28044             point2 = intersect(point1, point0);
28045             stream.point(point2[0], point2[1]);
28046           } else {
28047             // inside going out
28048             point2 = intersect(point0, point1);
28049             stream.point(point2[0], point2[1]);
28050             stream.lineEnd();
28051           }
28052           point0 = point2;
28053         } else if (notHemisphere && point0 && smallRadius ^ v) {
28054           var t;
28055           // If the codes for two points are different, or are both zero,
28056           // and there this segment intersects with the small circle.
28057           if (!(c & c0) && (t = intersect(point1, point0, true))) {
28058             clean = 0;
28059             if (smallRadius) {
28060               stream.lineStart();
28061               stream.point(t[0][0], t[0][1]);
28062               stream.point(t[1][0], t[1][1]);
28063               stream.lineEnd();
28064             } else {
28065               stream.point(t[1][0], t[1][1]);
28066               stream.lineEnd();
28067               stream.lineStart();
28068               stream.point(t[0][0], t[0][1]);
28069             }
28070           }
28071         }
28072         if (v && (!point0 || !pointEqual(point0, point1))) {
28073           stream.point(point1[0], point1[1]);
28074         }
28075         point0 = point1, v0 = v, c0 = c;
28076       },
28077       lineEnd: function() {
28078         if (v0) stream.lineEnd();
28079         point0 = null;
28080       },
28081       // Rejoin first and last segments if there were intersections and the first
28082       // and last points were visible.
28083       clean: function() {
28084         return clean | ((v00 && v0) << 1);
28085       }
28086     };
28087   }
28088
28089   // Intersects the great circle between a and b with the clip circle.
28090   function intersect(a, b, two) {
28091     var pa = cartesian(a),
28092         pb = cartesian(b);
28093
28094     // We have two planes, n1.p = d1 and n2.p = d2.
28095     // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
28096     var n1 = [1, 0, 0], // normal
28097         n2 = cartesianCross(pa, pb),
28098         n2n2 = cartesianDot(n2, n2),
28099         n1n2 = n2[0], // cartesianDot(n1, n2),
28100         determinant = n2n2 - n1n2 * n1n2;
28101
28102     // Two polar points.
28103     if (!determinant) return !two && a;
28104
28105     var c1 =  cr * n2n2 / determinant,
28106         c2 = -cr * n1n2 / determinant,
28107         n1xn2 = cartesianCross(n1, n2),
28108         A = cartesianScale(n1, c1),
28109         B = cartesianScale(n2, c2);
28110     cartesianAddInPlace(A, B);
28111
28112     // Solve |p(t)|^2 = 1.
28113     var u = n1xn2,
28114         w = cartesianDot(A, u),
28115         uu = cartesianDot(u, u),
28116         t2 = w * w - uu * (cartesianDot(A, A) - 1);
28117
28118     if (t2 < 0) return;
28119
28120     var t = sqrt(t2),
28121         q = cartesianScale(u, (-w - t) / uu);
28122     cartesianAddInPlace(q, A);
28123     q = spherical(q);
28124
28125     if (!two) return q;
28126
28127     // Two intersection points.
28128     var lambda0 = a[0],
28129         lambda1 = b[0],
28130         phi0 = a[1],
28131         phi1 = b[1],
28132         z;
28133
28134     if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
28135
28136     var delta = lambda1 - lambda0,
28137         polar = abs(delta - pi$3) < epsilon$2,
28138         meridian = polar || delta < epsilon$2;
28139
28140     if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
28141
28142     // Check that the first point is between a and b.
28143     if (meridian
28144         ? polar
28145           ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)
28146           : phi0 <= q[1] && q[1] <= phi1
28147         : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
28148       var q1 = cartesianScale(u, (-w + t) / uu);
28149       cartesianAddInPlace(q1, A);
28150       return [q, spherical(q1)];
28151     }
28152   }
28153
28154   // Generates a 4-bit vector representing the location of a point relative to
28155   // the small circle's bounding box.
28156   function code(lambda, phi) {
28157     var r = smallRadius ? radius : pi$3 - radius,
28158         code = 0;
28159     if (lambda < -r) code |= 1; // left
28160     else if (lambda > r) code |= 2; // right
28161     if (phi < -r) code |= 4; // below
28162     else if (phi > r) code |= 8; // above
28163     return code;
28164   }
28165
28166   return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);
28167 };
28168
28169 var transform = function(methods) {
28170   return {
28171     stream: transformer(methods)
28172   };
28173 };
28174
28175 function transformer(methods) {
28176   return function(stream) {
28177     var s = new TransformStream;
28178     for (var key in methods) s[key] = methods[key];
28179     s.stream = stream;
28180     return s;
28181   };
28182 }
28183
28184 function TransformStream() {}
28185
28186 TransformStream.prototype = {
28187   constructor: TransformStream,
28188   point: function(x, y) { this.stream.point(x, y); },
28189   sphere: function() { this.stream.sphere(); },
28190   lineStart: function() { this.stream.lineStart(); },
28191   lineEnd: function() { this.stream.lineEnd(); },
28192   polygonStart: function() { this.stream.polygonStart(); },
28193   polygonEnd: function() { this.stream.polygonEnd(); }
28194 };
28195
28196 function fitExtent(projection, extent, object) {
28197   var w = extent[1][0] - extent[0][0],
28198       h = extent[1][1] - extent[0][1],
28199       clip = projection.clipExtent && projection.clipExtent();
28200
28201   projection
28202       .scale(150)
28203       .translate([0, 0]);
28204
28205   if (clip != null) projection.clipExtent(null);
28206
28207   geoStream(object, projection.stream(boundsStream$1));
28208
28209   var b = boundsStream$1.result(),
28210       k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
28211       x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
28212       y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
28213
28214   if (clip != null) projection.clipExtent(clip);
28215
28216   return projection
28217       .scale(k * 150)
28218       .translate([x, y]);
28219 }
28220
28221 function fitSize(projection, size, object) {
28222   return fitExtent(projection, [[0, 0], size], object);
28223 }
28224
28225 var maxDepth = 16;
28226 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
28227
28228 var resample = function(project, delta2) {
28229   return +delta2 ? resample$1(project, delta2) : resampleNone(project);
28230 };
28231
28232 function resampleNone(project) {
28233   return transformer({
28234     point: function(x, y) {
28235       x = project(x, y);
28236       this.stream.point(x[0], x[1]);
28237     }
28238   });
28239 }
28240
28241 function resample$1(project, delta2) {
28242
28243   function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
28244     var dx = x1 - x0,
28245         dy = y1 - y0,
28246         d2 = dx * dx + dy * dy;
28247     if (d2 > 4 * delta2 && depth--) {
28248       var a = a0 + a1,
28249           b = b0 + b1,
28250           c = c0 + c1,
28251           m = sqrt(a * a + b * b + c * c),
28252           phi2 = asin(c /= m),
28253           lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
28254           p = project(lambda2, phi2),
28255           x2 = p[0],
28256           y2 = p[1],
28257           dx2 = x2 - x0,
28258           dy2 = y2 - y0,
28259           dz = dy * dx2 - dx * dy2;
28260       if (dz * dz / d2 > delta2 // perpendicular projected distance
28261           || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
28262           || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
28263         resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
28264         stream.point(x2, y2);
28265         resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
28266       }
28267     }
28268   }
28269   return function(stream) {
28270     var lambda00, x00, y00, a00, b00, c00, // first point
28271         lambda0, x0, y0, a0, b0, c0; // previous point
28272
28273     var resampleStream = {
28274       point: point,
28275       lineStart: lineStart,
28276       lineEnd: lineEnd,
28277       polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
28278       polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
28279     };
28280
28281     function point(x, y) {
28282       x = project(x, y);
28283       stream.point(x[0], x[1]);
28284     }
28285
28286     function lineStart() {
28287       x0 = NaN;
28288       resampleStream.point = linePoint;
28289       stream.lineStart();
28290     }
28291
28292     function linePoint(lambda, phi) {
28293       var c = cartesian([lambda, phi]), p = project(lambda, phi);
28294       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);
28295       stream.point(x0, y0);
28296     }
28297
28298     function lineEnd() {
28299       resampleStream.point = point;
28300       stream.lineEnd();
28301     }
28302
28303     function ringStart() {
28304       lineStart();
28305       resampleStream.point = ringPoint;
28306       resampleStream.lineEnd = ringEnd;
28307     }
28308
28309     function ringPoint(lambda, phi) {
28310       linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
28311       resampleStream.point = linePoint;
28312     }
28313
28314     function ringEnd() {
28315       resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
28316       resampleStream.lineEnd = lineEnd;
28317       lineEnd();
28318     }
28319
28320     return resampleStream;
28321   };
28322 }
28323
28324 var transformRadians = transformer({
28325   point: function(x, y) {
28326     this.stream.point(x * radians, y * radians);
28327   }
28328 });
28329
28330 function projection(project) {
28331   return projectionMutator(function() { return project; })();
28332 }
28333
28334 function projectionMutator(projectAt) {
28335   var project,
28336       k = 150, // scale
28337       x = 480, y = 250, // translate
28338       dx, dy, lambda = 0, phi = 0, // center
28339       deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
28340       theta = null, preclip = clipAntimeridian, // clip angle
28341       x0 = null, y0, x1, y1, postclip = identity$4, // clip extent
28342       delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
28343       cache,
28344       cacheStream;
28345
28346   function projection(point) {
28347     point = projectRotate(point[0] * radians, point[1] * radians);
28348     return [point[0] * k + dx, dy - point[1] * k];
28349   }
28350
28351   function invert(point) {
28352     point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
28353     return point && [point[0] * degrees$1, point[1] * degrees$1];
28354   }
28355
28356   function projectTransform(x, y) {
28357     return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
28358   }
28359
28360   projection.stream = function(stream) {
28361     return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));
28362   };
28363
28364   projection.clipAngle = function(_) {
28365     return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
28366   };
28367
28368   projection.clipExtent = function(_) {
28369     return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
28370   };
28371
28372   projection.scale = function(_) {
28373     return arguments.length ? (k = +_, recenter()) : k;
28374   };
28375
28376   projection.translate = function(_) {
28377     return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
28378   };
28379
28380   projection.center = function(_) {
28381     return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
28382   };
28383
28384   projection.rotate = function(_) {
28385     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];
28386   };
28387
28388   projection.precision = function(_) {
28389     return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
28390   };
28391
28392   projection.fitExtent = function(extent, object) {
28393     return fitExtent(projection, extent, object);
28394   };
28395
28396   projection.fitSize = function(size, object) {
28397     return fitSize(projection, size, object);
28398   };
28399
28400   function recenter() {
28401     projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
28402     var center = project(lambda, phi);
28403     dx = x - center[0] * k;
28404     dy = y + center[1] * k;
28405     return reset();
28406   }
28407
28408   function reset() {
28409     cache = cacheStream = null;
28410     return projection;
28411   }
28412
28413   return function() {
28414     project = projectAt.apply(this, arguments);
28415     projection.invert = project.invert && invert;
28416     return recenter();
28417   };
28418 }
28419
28420 function conicProjection(projectAt) {
28421   var phi0 = 0,
28422       phi1 = pi$3 / 3,
28423       m = projectionMutator(projectAt),
28424       p = m(phi0, phi1);
28425
28426   p.parallels = function(_) {
28427     return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
28428   };
28429
28430   return p;
28431 }
28432
28433 function cylindricalEqualAreaRaw(phi0) {
28434   var cosPhi0 = cos$1(phi0);
28435
28436   function forward(lambda, phi) {
28437     return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
28438   }
28439
28440   forward.invert = function(x, y) {
28441     return [x / cosPhi0, asin(y * cosPhi0)];
28442   };
28443
28444   return forward;
28445 }
28446
28447 function conicEqualAreaRaw(y0, y1) {
28448   var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
28449
28450   // Are the parallels symmetrical around the Equator?
28451   if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);
28452
28453   var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
28454
28455   function project(x, y) {
28456     var r = sqrt(c - 2 * n * sin$1(y)) / n;
28457     return [r * sin$1(x *= n), r0 - r * cos$1(x)];
28458   }
28459
28460   project.invert = function(x, y) {
28461     var r0y = r0 - y;
28462     return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
28463   };
28464
28465   return project;
28466 }
28467
28468 var conicEqualArea = function() {
28469   return conicProjection(conicEqualAreaRaw)
28470       .scale(155.424)
28471       .center([0, 33.6442]);
28472 };
28473
28474 var albers = function() {
28475   return conicEqualArea()
28476       .parallels([29.5, 45.5])
28477       .scale(1070)
28478       .translate([480, 250])
28479       .rotate([96, 0])
28480       .center([-0.6, 38.7]);
28481 };
28482
28483 // The projections must have mutually exclusive clip regions on the sphere,
28484 // as this will avoid emitting interleaving lines and polygons.
28485 function multiplex(streams) {
28486   var n = streams.length;
28487   return {
28488     point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
28489     sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
28490     lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
28491     lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
28492     polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
28493     polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
28494   };
28495 }
28496
28497 // A composite projection for the United States, configured by default for
28498 // 960×500. The projection also works quite well at 960×600 if you change the
28499 // scale to 1285 and adjust the translate accordingly. The set of standard
28500 // parallels for each region comes from USGS, which is published here:
28501 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
28502 var albersUsa = function() {
28503   var cache,
28504       cacheStream,
28505       lower48 = albers(), lower48Point,
28506       alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
28507       hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
28508       point, pointStream = {point: function(x, y) { point = [x, y]; }};
28509
28510   function albersUsa(coordinates) {
28511     var x = coordinates[0], y = coordinates[1];
28512     return point = null,
28513         (lower48Point.point(x, y), point)
28514         || (alaskaPoint.point(x, y), point)
28515         || (hawaiiPoint.point(x, y), point);
28516   }
28517
28518   albersUsa.invert = function(coordinates) {
28519     var k = lower48.scale(),
28520         t = lower48.translate(),
28521         x = (coordinates[0] - t[0]) / k,
28522         y = (coordinates[1] - t[1]) / k;
28523     return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
28524         : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
28525         : lower48).invert(coordinates);
28526   };
28527
28528   albersUsa.stream = function(stream) {
28529     return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
28530   };
28531
28532   albersUsa.precision = function(_) {
28533     if (!arguments.length) return lower48.precision();
28534     lower48.precision(_), alaska.precision(_), hawaii.precision(_);
28535     return reset();
28536   };
28537
28538   albersUsa.scale = function(_) {
28539     if (!arguments.length) return lower48.scale();
28540     lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
28541     return albersUsa.translate(lower48.translate());
28542   };
28543
28544   albersUsa.translate = function(_) {
28545     if (!arguments.length) return lower48.translate();
28546     var k = lower48.scale(), x = +_[0], y = +_[1];
28547
28548     lower48Point = lower48
28549         .translate(_)
28550         .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
28551         .stream(pointStream);
28552
28553     alaskaPoint = alaska
28554         .translate([x - 0.307 * k, y + 0.201 * k])
28555         .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
28556         .stream(pointStream);
28557
28558     hawaiiPoint = hawaii
28559         .translate([x - 0.205 * k, y + 0.212 * k])
28560         .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
28561         .stream(pointStream);
28562
28563     return reset();
28564   };
28565
28566   albersUsa.fitExtent = function(extent, object) {
28567     return fitExtent(albersUsa, extent, object);
28568   };
28569
28570   albersUsa.fitSize = function(size, object) {
28571     return fitSize(albersUsa, size, object);
28572   };
28573
28574   function reset() {
28575     cache = cacheStream = null;
28576     return albersUsa;
28577   }
28578
28579   return albersUsa.scale(1070);
28580 };
28581
28582 function azimuthalRaw(scale) {
28583   return function(x, y) {
28584     var cx = cos$1(x),
28585         cy = cos$1(y),
28586         k = scale(cx * cy);
28587     return [
28588       k * cy * sin$1(x),
28589       k * sin$1(y)
28590     ];
28591   }
28592 }
28593
28594 function azimuthalInvert(angle) {
28595   return function(x, y) {
28596     var z = sqrt(x * x + y * y),
28597         c = angle(z),
28598         sc = sin$1(c),
28599         cc = cos$1(c);
28600     return [
28601       atan2(x * sc, z * cc),
28602       asin(z && y * sc / z)
28603     ];
28604   }
28605 }
28606
28607 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
28608   return sqrt(2 / (1 + cxcy));
28609 });
28610
28611 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
28612   return 2 * asin(z / 2);
28613 });
28614
28615 var azimuthalEqualArea = function() {
28616   return projection(azimuthalEqualAreaRaw)
28617       .scale(124.75)
28618       .clipAngle(180 - 1e-3);
28619 };
28620
28621 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
28622   return (c = acos(c)) && c / sin$1(c);
28623 });
28624
28625 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
28626   return z;
28627 });
28628
28629 var azimuthalEquidistant = function() {
28630   return projection(azimuthalEquidistantRaw)
28631       .scale(79.4188)
28632       .clipAngle(180 - 1e-3);
28633 };
28634
28635 function mercatorRaw(lambda, phi) {
28636   return [lambda, log(tan((halfPi$2 + phi) / 2))];
28637 }
28638
28639 mercatorRaw.invert = function(x, y) {
28640   return [x, 2 * atan(exp(y)) - halfPi$2];
28641 };
28642
28643 var mercator = function() {
28644   return mercatorProjection(mercatorRaw)
28645       .scale(961 / tau$3);
28646 };
28647
28648 function mercatorProjection(project) {
28649   var m = projection(project),
28650       center = m.center,
28651       scale = m.scale,
28652       translate = m.translate,
28653       clipExtent = m.clipExtent,
28654       x0 = null, y0, x1, y1; // clip extent
28655
28656   m.scale = function(_) {
28657     return arguments.length ? (scale(_), reclip()) : scale();
28658   };
28659
28660   m.translate = function(_) {
28661     return arguments.length ? (translate(_), reclip()) : translate();
28662   };
28663
28664   m.center = function(_) {
28665     return arguments.length ? (center(_), reclip()) : center();
28666   };
28667
28668   m.clipExtent = function(_) {
28669     return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];
28670   };
28671
28672   function reclip() {
28673     var k = pi$3 * scale(),
28674         t = m(rotation(m.rotate()).invert([0, 0]));
28675     return clipExtent(x0 == null
28676         ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
28677         ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
28678         : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
28679   }
28680
28681   return reclip();
28682 }
28683
28684 function tany(y) {
28685   return tan((halfPi$2 + y) / 2);
28686 }
28687
28688 function conicConformalRaw(y0, y1) {
28689   var cy0 = cos$1(y0),
28690       n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),
28691       f = cy0 * pow(tany(y0), n) / n;
28692
28693   if (!n) return mercatorRaw;
28694
28695   function project(x, y) {
28696     if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }
28697     else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }
28698     var r = f / pow(tany(y), n);
28699     return [r * sin$1(n * x), f - r * cos$1(n * x)];
28700   }
28701
28702   project.invert = function(x, y) {
28703     var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);
28704     return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];
28705   };
28706
28707   return project;
28708 }
28709
28710 var conicConformal = function() {
28711   return conicProjection(conicConformalRaw)
28712       .scale(109.5)
28713       .parallels([30, 30]);
28714 };
28715
28716 function equirectangularRaw(lambda, phi) {
28717   return [lambda, phi];
28718 }
28719
28720 equirectangularRaw.invert = equirectangularRaw;
28721
28722 var equirectangular = function() {
28723   return projection(equirectangularRaw)
28724       .scale(152.63);
28725 };
28726
28727 function conicEquidistantRaw(y0, y1) {
28728   var cy0 = cos$1(y0),
28729       n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
28730       g = cy0 / n + y0;
28731
28732   if (abs(n) < epsilon$2) return equirectangularRaw;
28733
28734   function project(x, y) {
28735     var gy = g - y, nx = n * x;
28736     return [gy * sin$1(nx), g - gy * cos$1(nx)];
28737   }
28738
28739   project.invert = function(x, y) {
28740     var gy = g - y;
28741     return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];
28742   };
28743
28744   return project;
28745 }
28746
28747 var conicEquidistant = function() {
28748   return conicProjection(conicEquidistantRaw)
28749       .scale(131.154)
28750       .center([0, 13.9389]);
28751 };
28752
28753 function gnomonicRaw(x, y) {
28754   var cy = cos$1(y), k = cos$1(x) * cy;
28755   return [cy * sin$1(x) / k, sin$1(y) / k];
28756 }
28757
28758 gnomonicRaw.invert = azimuthalInvert(atan);
28759
28760 var gnomonic = function() {
28761   return projection(gnomonicRaw)
28762       .scale(144.049)
28763       .clipAngle(60);
28764 };
28765
28766 function scaleTranslate(kx, ky, tx, ty) {
28767   return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({
28768     point: function(x, y) {
28769       this.stream.point(x * kx + tx, y * ky + ty);
28770     }
28771   });
28772 }
28773
28774 var identity$5 = function() {
28775   var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform$$1 = identity$4, // scale, translate and reflect
28776       x0 = null, y0, x1, y1, clip = identity$4, // clip extent
28777       cache,
28778       cacheStream,
28779       projection;
28780
28781   function reset() {
28782     cache = cacheStream = null;
28783     return projection;
28784   }
28785
28786   return projection = {
28787     stream: function(stream) {
28788       return cache && cacheStream === stream ? cache : cache = transform$$1(clip(cacheStream = stream));
28789     },
28790     clipExtent: function(_) {
28791       return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
28792     },
28793     scale: function(_) {
28794       return arguments.length ? (transform$$1 = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
28795     },
28796     translate: function(_) {
28797       return arguments.length ? (transform$$1 = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
28798     },
28799     reflectX: function(_) {
28800       return arguments.length ? (transform$$1 = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
28801     },
28802     reflectY: function(_) {
28803       return arguments.length ? (transform$$1 = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
28804     },
28805     fitExtent: function(extent, object) {
28806       return fitExtent(projection, extent, object);
28807     },
28808     fitSize: function(size, object) {
28809       return fitSize(projection, size, object);
28810     }
28811   };
28812 };
28813
28814 function orthographicRaw(x, y) {
28815   return [cos$1(y) * sin$1(x), sin$1(y)];
28816 }
28817
28818 orthographicRaw.invert = azimuthalInvert(asin);
28819
28820 var orthographic = function() {
28821   return projection(orthographicRaw)
28822       .scale(249.5)
28823       .clipAngle(90 + epsilon$2);
28824 };
28825
28826 function stereographicRaw(x, y) {
28827   var cy = cos$1(y), k = 1 + cos$1(x) * cy;
28828   return [cy * sin$1(x) / k, sin$1(y) / k];
28829 }
28830
28831 stereographicRaw.invert = azimuthalInvert(function(z) {
28832   return 2 * atan(z);
28833 });
28834
28835 var stereographic = function() {
28836   return projection(stereographicRaw)
28837       .scale(250)
28838       .clipAngle(142);
28839 };
28840
28841 function transverseMercatorRaw(lambda, phi) {
28842   return [log(tan((halfPi$2 + phi) / 2)), -lambda];
28843 }
28844
28845 transverseMercatorRaw.invert = function(x, y) {
28846   return [-y, 2 * atan(exp(x)) - halfPi$2];
28847 };
28848
28849 var transverseMercator = function() {
28850   var m = mercatorProjection(transverseMercatorRaw),
28851       center = m.center,
28852       rotate = m.rotate;
28853
28854   m.center = function(_) {
28855     return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
28856   };
28857
28858   m.rotate = function(_) {
28859     return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
28860   };
28861
28862   return rotate([0, 0, 90])
28863       .scale(159.155);
28864 };
28865
28866 function defaultSeparation(a, b) {
28867   return a.parent === b.parent ? 1 : 2;
28868 }
28869
28870 function meanX(children) {
28871   return children.reduce(meanXReduce, 0) / children.length;
28872 }
28873
28874 function meanXReduce(x, c) {
28875   return x + c.x;
28876 }
28877
28878 function maxY(children) {
28879   return 1 + children.reduce(maxYReduce, 0);
28880 }
28881
28882 function maxYReduce(y, c) {
28883   return Math.max(y, c.y);
28884 }
28885
28886 function leafLeft(node) {
28887   var children;
28888   while (children = node.children) node = children[0];
28889   return node;
28890 }
28891
28892 function leafRight(node) {
28893   var children;
28894   while (children = node.children) node = children[children.length - 1];
28895   return node;
28896 }
28897
28898 var cluster = function() {
28899   var separation = defaultSeparation,
28900       dx = 1,
28901       dy = 1,
28902       nodeSize = false;
28903
28904   function cluster(root) {
28905     var previousNode,
28906         x = 0;
28907
28908     // First walk, computing the initial x & y values.
28909     root.eachAfter(function(node) {
28910       var children = node.children;
28911       if (children) {
28912         node.x = meanX(children);
28913         node.y = maxY(children);
28914       } else {
28915         node.x = previousNode ? x += separation(node, previousNode) : 0;
28916         node.y = 0;
28917         previousNode = node;
28918       }
28919     });
28920
28921     var left = leafLeft(root),
28922         right = leafRight(root),
28923         x0 = left.x - separation(left, right) / 2,
28924         x1 = right.x + separation(right, left) / 2;
28925
28926     // Second walk, normalizing x & y to the desired size.
28927     return root.eachAfter(nodeSize ? function(node) {
28928       node.x = (node.x - root.x) * dx;
28929       node.y = (root.y - node.y) * dy;
28930     } : function(node) {
28931       node.x = (node.x - x0) / (x1 - x0) * dx;
28932       node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
28933     });
28934   }
28935
28936   cluster.separation = function(x) {
28937     return arguments.length ? (separation = x, cluster) : separation;
28938   };
28939
28940   cluster.size = function(x) {
28941     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
28942   };
28943
28944   cluster.nodeSize = function(x) {
28945     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
28946   };
28947
28948   return cluster;
28949 };
28950
28951 function count(node) {
28952   var sum = 0,
28953       children = node.children,
28954       i = children && children.length;
28955   if (!i) sum = 1;
28956   else while (--i >= 0) sum += children[i].value;
28957   node.value = sum;
28958 }
28959
28960 var node_count = function() {
28961   return this.eachAfter(count);
28962 };
28963
28964 var node_each = function(callback) {
28965   var node = this, current, next = [node], children, i, n;
28966   do {
28967     current = next.reverse(), next = [];
28968     while (node = current.pop()) {
28969       callback(node), children = node.children;
28970       if (children) for (i = 0, n = children.length; i < n; ++i) {
28971         next.push(children[i]);
28972       }
28973     }
28974   } while (next.length);
28975   return this;
28976 };
28977
28978 var node_eachBefore = function(callback) {
28979   var node = this, nodes = [node], children, i;
28980   while (node = nodes.pop()) {
28981     callback(node), children = node.children;
28982     if (children) for (i = children.length - 1; i >= 0; --i) {
28983       nodes.push(children[i]);
28984     }
28985   }
28986   return this;
28987 };
28988
28989 var node_eachAfter = function(callback) {
28990   var node = this, nodes = [node], next = [], children, i, n;
28991   while (node = nodes.pop()) {
28992     next.push(node), children = node.children;
28993     if (children) for (i = 0, n = children.length; i < n; ++i) {
28994       nodes.push(children[i]);
28995     }
28996   }
28997   while (node = next.pop()) {
28998     callback(node);
28999   }
29000   return this;
29001 };
29002
29003 var node_sum = function(value) {
29004   return this.eachAfter(function(node) {
29005     var sum = +value(node.data) || 0,
29006         children = node.children,
29007         i = children && children.length;
29008     while (--i >= 0) sum += children[i].value;
29009     node.value = sum;
29010   });
29011 };
29012
29013 var node_sort = function(compare) {
29014   return this.eachBefore(function(node) {
29015     if (node.children) {
29016       node.children.sort(compare);
29017     }
29018   });
29019 };
29020
29021 var node_path = function(end) {
29022   var start = this,
29023       ancestor = leastCommonAncestor(start, end),
29024       nodes = [start];
29025   while (start !== ancestor) {
29026     start = start.parent;
29027     nodes.push(start);
29028   }
29029   var k = nodes.length;
29030   while (end !== ancestor) {
29031     nodes.splice(k, 0, end);
29032     end = end.parent;
29033   }
29034   return nodes;
29035 };
29036
29037 function leastCommonAncestor(a, b) {
29038   if (a === b) return a;
29039   var aNodes = a.ancestors(),
29040       bNodes = b.ancestors(),
29041       c = null;
29042   a = aNodes.pop();
29043   b = bNodes.pop();
29044   while (a === b) {
29045     c = a;
29046     a = aNodes.pop();
29047     b = bNodes.pop();
29048   }
29049   return c;
29050 }
29051
29052 var node_ancestors = function() {
29053   var node = this, nodes = [node];
29054   while (node = node.parent) {
29055     nodes.push(node);
29056   }
29057   return nodes;
29058 };
29059
29060 var node_descendants = function() {
29061   var nodes = [];
29062   this.each(function(node) {
29063     nodes.push(node);
29064   });
29065   return nodes;
29066 };
29067
29068 var node_leaves = function() {
29069   var leaves = [];
29070   this.eachBefore(function(node) {
29071     if (!node.children) {
29072       leaves.push(node);
29073     }
29074   });
29075   return leaves;
29076 };
29077
29078 var node_links = function() {
29079   var root = this, links = [];
29080   root.each(function(node) {
29081     if (node !== root) { // Don’t include the root’s parent, if any.
29082       links.push({source: node.parent, target: node});
29083     }
29084   });
29085   return links;
29086 };
29087
29088 function hierarchy(data, children) {
29089   var root = new Node(data),
29090       valued = +data.value && (root.value = data.value),
29091       node,
29092       nodes = [root],
29093       child,
29094       childs,
29095       i,
29096       n;
29097
29098   if (children == null) children = defaultChildren;
29099
29100   while (node = nodes.pop()) {
29101     if (valued) node.value = +node.data.value;
29102     if ((childs = children(node.data)) && (n = childs.length)) {
29103       node.children = new Array(n);
29104       for (i = n - 1; i >= 0; --i) {
29105         nodes.push(child = node.children[i] = new Node(childs[i]));
29106         child.parent = node;
29107         child.depth = node.depth + 1;
29108       }
29109     }
29110   }
29111
29112   return root.eachBefore(computeHeight);
29113 }
29114
29115 function node_copy() {
29116   return hierarchy(this).eachBefore(copyData);
29117 }
29118
29119 function defaultChildren(d) {
29120   return d.children;
29121 }
29122
29123 function copyData(node) {
29124   node.data = node.data.data;
29125 }
29126
29127 function computeHeight(node) {
29128   var height = 0;
29129   do node.height = height;
29130   while ((node = node.parent) && (node.height < ++height));
29131 }
29132
29133 function Node(data) {
29134   this.data = data;
29135   this.depth =
29136   this.height = 0;
29137   this.parent = null;
29138 }
29139
29140 Node.prototype = hierarchy.prototype = {
29141   constructor: Node,
29142   count: node_count,
29143   each: node_each,
29144   eachAfter: node_eachAfter,
29145   eachBefore: node_eachBefore,
29146   sum: node_sum,
29147   sort: node_sort,
29148   path: node_path,
29149   ancestors: node_ancestors,
29150   descendants: node_descendants,
29151   leaves: node_leaves,
29152   links: node_links,
29153   copy: node_copy
29154 };
29155
29156 var slice$3 = Array.prototype.slice;
29157
29158 function shuffle$1(array) {
29159   var m = array.length,
29160       t,
29161       i;
29162
29163   while (m) {
29164     i = Math.random() * m-- | 0;
29165     t = array[m];
29166     array[m] = array[i];
29167     array[i] = t;
29168   }
29169
29170   return array;
29171 }
29172
29173 var enclose = function(circles) {
29174   var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;
29175
29176   while (i < n) {
29177     p = circles[i];
29178     if (e && enclosesWeak(e, p)) ++i;
29179     else e = encloseBasis(B = extendBasis(B, p)), i = 0;
29180   }
29181
29182   return e;
29183 };
29184
29185 function extendBasis(B, p) {
29186   var i, j;
29187
29188   if (enclosesWeakAll(p, B)) return [p];
29189
29190   // If we get here then B must have at least one element.
29191   for (i = 0; i < B.length; ++i) {
29192     if (enclosesNot(p, B[i])
29193         && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
29194       return [B[i], p];
29195     }
29196   }
29197
29198   // If we get here then B must have at least two elements.
29199   for (i = 0; i < B.length - 1; ++i) {
29200     for (j = i + 1; j < B.length; ++j) {
29201       if (enclosesNot(encloseBasis2(B[i], B[j]), p)
29202           && enclosesNot(encloseBasis2(B[i], p), B[j])
29203           && enclosesNot(encloseBasis2(B[j], p), B[i])
29204           && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
29205         return [B[i], B[j], p];
29206       }
29207     }
29208   }
29209
29210   // If we get here then something is very wrong.
29211   throw new Error;
29212 }
29213
29214 function enclosesNot(a, b) {
29215   var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
29216   return dr < 0 || dr * dr < dx * dx + dy * dy;
29217 }
29218
29219 function enclosesWeak(a, b) {
29220   var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;
29221   return dr > 0 && dr * dr > dx * dx + dy * dy;
29222 }
29223
29224 function enclosesWeakAll(a, B) {
29225   for (var i = 0; i < B.length; ++i) {
29226     if (!enclosesWeak(a, B[i])) {
29227       return false;
29228     }
29229   }
29230   return true;
29231 }
29232
29233 function encloseBasis(B) {
29234   switch (B.length) {
29235     case 1: return encloseBasis1(B[0]);
29236     case 2: return encloseBasis2(B[0], B[1]);
29237     case 3: return encloseBasis3(B[0], B[1], B[2]);
29238   }
29239 }
29240
29241 function encloseBasis1(a) {
29242   return {
29243     x: a.x,
29244     y: a.y,
29245     r: a.r
29246   };
29247 }
29248
29249 function encloseBasis2(a, b) {
29250   var x1 = a.x, y1 = a.y, r1 = a.r,
29251       x2 = b.x, y2 = b.y, r2 = b.r,
29252       x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
29253       l = Math.sqrt(x21 * x21 + y21 * y21);
29254   return {
29255     x: (x1 + x2 + x21 / l * r21) / 2,
29256     y: (y1 + y2 + y21 / l * r21) / 2,
29257     r: (l + r1 + r2) / 2
29258   };
29259 }
29260
29261 function encloseBasis3(a, b, c) {
29262   var x1 = a.x, y1 = a.y, r1 = a.r,
29263       x2 = b.x, y2 = b.y, r2 = b.r,
29264       x3 = c.x, y3 = c.y, r3 = c.r,
29265       a2 = x1 - x2,
29266       a3 = x1 - x3,
29267       b2 = y1 - y2,
29268       b3 = y1 - y3,
29269       c2 = r2 - r1,
29270       c3 = r3 - r1,
29271       d1 = x1 * x1 + y1 * y1 - r1 * r1,
29272       d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
29273       d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
29274       ab = a3 * b2 - a2 * b3,
29275       xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
29276       xb = (b3 * c2 - b2 * c3) / ab,
29277       ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
29278       yb = (a2 * c3 - a3 * c2) / ab,
29279       A = xb * xb + yb * yb - 1,
29280       B = 2 * (r1 + xa * xb + ya * yb),
29281       C = xa * xa + ya * ya - r1 * r1,
29282       r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
29283   return {
29284     x: x1 + xa + xb * r,
29285     y: y1 + ya + yb * r,
29286     r: r
29287   };
29288 }
29289
29290 function place(a, b, c) {
29291   var ax = a.x,
29292       ay = a.y,
29293       da = b.r + c.r,
29294       db = a.r + c.r,
29295       dx = b.x - ax,
29296       dy = b.y - ay,
29297       dc = dx * dx + dy * dy;
29298   if (dc) {
29299     var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
29300         y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
29301     c.x = ax + x * dx + y * dy;
29302     c.y = ay + x * dy - y * dx;
29303   } else {
29304     c.x = ax + db;
29305     c.y = ay;
29306   }
29307 }
29308
29309 function intersects(a, b) {
29310   var dx = b.x - a.x,
29311       dy = b.y - a.y,
29312       dr = a.r + b.r;
29313   return dr * dr - 1e-6 > dx * dx + dy * dy;
29314 }
29315
29316 function score(node) {
29317   var a = node._,
29318       b = node.next._,
29319       ab = a.r + b.r,
29320       dx = (a.x * b.r + b.x * a.r) / ab,
29321       dy = (a.y * b.r + b.y * a.r) / ab;
29322   return dx * dx + dy * dy;
29323 }
29324
29325 function Node$1(circle) {
29326   this._ = circle;
29327   this.next = null;
29328   this.previous = null;
29329 }
29330
29331 function packEnclose(circles) {
29332   if (!(n = circles.length)) return 0;
29333
29334   var a, b, c, n, aa, ca, i, j, k, sj, sk;
29335
29336   // Place the first circle.
29337   a = circles[0], a.x = 0, a.y = 0;
29338   if (!(n > 1)) return a.r;
29339
29340   // Place the second circle.
29341   b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
29342   if (!(n > 2)) return a.r + b.r;
29343
29344   // Place the third circle.
29345   place(b, a, c = circles[2]);
29346
29347   // Initialize the front-chain using the first three circles a, b and c.
29348   a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
29349   a.next = c.previous = b;
29350   b.next = a.previous = c;
29351   c.next = b.previous = a;
29352
29353   // Attempt to place each remaining circle…
29354   pack: for (i = 3; i < n; ++i) {
29355     place(a._, b._, c = circles[i]), c = new Node$1(c);
29356
29357     // Find the closest intersecting circle on the front-chain, if any.
29358     // “Closeness” is determined by linear distance along the front-chain.
29359     // “Ahead” or “behind” is likewise determined by linear distance.
29360     j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
29361     do {
29362       if (sj <= sk) {
29363         if (intersects(j._, c._)) {
29364           b = j, a.next = b, b.previous = a, --i;
29365           continue pack;
29366         }
29367         sj += j._.r, j = j.next;
29368       } else {
29369         if (intersects(k._, c._)) {
29370           a = k, a.next = b, b.previous = a, --i;
29371           continue pack;
29372         }
29373         sk += k._.r, k = k.previous;
29374       }
29375     } while (j !== k.next);
29376
29377     // Success! Insert the new circle c between a and b.
29378     c.previous = a, c.next = b, a.next = b.previous = b = c;
29379
29380     // Compute the new closest circle pair to the centroid.
29381     aa = score(a);
29382     while ((c = c.next) !== b) {
29383       if ((ca = score(c)) < aa) {
29384         a = c, aa = ca;
29385       }
29386     }
29387     b = a.next;
29388   }
29389
29390   // Compute the enclosing circle of the front chain.
29391   a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
29392
29393   // Translate the circles to put the enclosing circle around the origin.
29394   for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
29395
29396   return c.r;
29397 }
29398
29399 var siblings = function(circles) {
29400   packEnclose(circles);
29401   return circles;
29402 };
29403
29404 function optional(f) {
29405   return f == null ? null : required(f);
29406 }
29407
29408 function required(f) {
29409   if (typeof f !== "function") throw new Error;
29410   return f;
29411 }
29412
29413 function constantZero() {
29414   return 0;
29415 }
29416
29417 var constant$8 = function(x) {
29418   return function() {
29419     return x;
29420   };
29421 };
29422
29423 function defaultRadius$1(d) {
29424   return Math.sqrt(d.value);
29425 }
29426
29427 var index$5 = function() {
29428   var radius = null,
29429       dx = 1,
29430       dy = 1,
29431       padding = constantZero;
29432
29433   function pack(root) {
29434     root.x = dx / 2, root.y = dy / 2;
29435     if (radius) {
29436       root.eachBefore(radiusLeaf(radius))
29437           .eachAfter(packChildren(padding, 0.5))
29438           .eachBefore(translateChild(1));
29439     } else {
29440       root.eachBefore(radiusLeaf(defaultRadius$1))
29441           .eachAfter(packChildren(constantZero, 1))
29442           .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
29443           .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
29444     }
29445     return root;
29446   }
29447
29448   pack.radius = function(x) {
29449     return arguments.length ? (radius = optional(x), pack) : radius;
29450   };
29451
29452   pack.size = function(x) {
29453     return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
29454   };
29455
29456   pack.padding = function(x) {
29457     return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding;
29458   };
29459
29460   return pack;
29461 };
29462
29463 function radiusLeaf(radius) {
29464   return function(node) {
29465     if (!node.children) {
29466       node.r = Math.max(0, +radius(node) || 0);
29467     }
29468   };
29469 }
29470
29471 function packChildren(padding, k) {
29472   return function(node) {
29473     if (children = node.children) {
29474       var children,
29475           i,
29476           n = children.length,
29477           r = padding(node) * k || 0,
29478           e;
29479
29480       if (r) for (i = 0; i < n; ++i) children[i].r += r;
29481       e = packEnclose(children);
29482       if (r) for (i = 0; i < n; ++i) children[i].r -= r;
29483       node.r = e + r;
29484     }
29485   };
29486 }
29487
29488 function translateChild(k) {
29489   return function(node) {
29490     var parent = node.parent;
29491     node.r *= k;
29492     if (parent) {
29493       node.x = parent.x + k * node.x;
29494       node.y = parent.y + k * node.y;
29495     }
29496   };
29497 }
29498
29499 var roundNode = function(node) {
29500   node.x0 = Math.round(node.x0);
29501   node.y0 = Math.round(node.y0);
29502   node.x1 = Math.round(node.x1);
29503   node.y1 = Math.round(node.y1);
29504 };
29505
29506 var treemapDice = function(parent, x0, y0, x1, y1) {
29507   var nodes = parent.children,
29508       node,
29509       i = -1,
29510       n = nodes.length,
29511       k = parent.value && (x1 - x0) / parent.value;
29512
29513   while (++i < n) {
29514     node = nodes[i], node.y0 = y0, node.y1 = y1;
29515     node.x0 = x0, node.x1 = x0 += node.value * k;
29516   }
29517 };
29518
29519 var partition = function() {
29520   var dx = 1,
29521       dy = 1,
29522       padding = 0,
29523       round = false;
29524
29525   function partition(root) {
29526     var n = root.height + 1;
29527     root.x0 =
29528     root.y0 = padding;
29529     root.x1 = dx;
29530     root.y1 = dy / n;
29531     root.eachBefore(positionNode(dy, n));
29532     if (round) root.eachBefore(roundNode);
29533     return root;
29534   }
29535
29536   function positionNode(dy, n) {
29537     return function(node) {
29538       if (node.children) {
29539         treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
29540       }
29541       var x0 = node.x0,
29542           y0 = node.y0,
29543           x1 = node.x1 - padding,
29544           y1 = node.y1 - padding;
29545       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29546       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29547       node.x0 = x0;
29548       node.y0 = y0;
29549       node.x1 = x1;
29550       node.y1 = y1;
29551     };
29552   }
29553
29554   partition.round = function(x) {
29555     return arguments.length ? (round = !!x, partition) : round;
29556   };
29557
29558   partition.size = function(x) {
29559     return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
29560   };
29561
29562   partition.padding = function(x) {
29563     return arguments.length ? (padding = +x, partition) : padding;
29564   };
29565
29566   return partition;
29567 };
29568
29569 var keyPrefix$1 = "$";
29570 var preroot = {depth: -1};
29571 var ambiguous = {};
29572
29573 function defaultId(d) {
29574   return d.id;
29575 }
29576
29577 function defaultParentId(d) {
29578   return d.parentId;
29579 }
29580
29581 var stratify = function() {
29582   var id = defaultId,
29583       parentId = defaultParentId;
29584
29585   function stratify(data) {
29586     var d,
29587         i,
29588         n = data.length,
29589         root,
29590         parent,
29591         node,
29592         nodes = new Array(n),
29593         nodeId,
29594         nodeKey,
29595         nodeByKey = {};
29596
29597     for (i = 0; i < n; ++i) {
29598       d = data[i], node = nodes[i] = new Node(d);
29599       if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
29600         nodeKey = keyPrefix$1 + (node.id = nodeId);
29601         nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
29602       }
29603     }
29604
29605     for (i = 0; i < n; ++i) {
29606       node = nodes[i], nodeId = parentId(data[i], i, data);
29607       if (nodeId == null || !(nodeId += "")) {
29608         if (root) throw new Error("multiple roots");
29609         root = node;
29610       } else {
29611         parent = nodeByKey[keyPrefix$1 + nodeId];
29612         if (!parent) throw new Error("missing: " + nodeId);
29613         if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
29614         if (parent.children) parent.children.push(node);
29615         else parent.children = [node];
29616         node.parent = parent;
29617       }
29618     }
29619
29620     if (!root) throw new Error("no root");
29621     root.parent = preroot;
29622     root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
29623     root.parent = null;
29624     if (n > 0) throw new Error("cycle");
29625
29626     return root;
29627   }
29628
29629   stratify.id = function(x) {
29630     return arguments.length ? (id = required(x), stratify) : id;
29631   };
29632
29633   stratify.parentId = function(x) {
29634     return arguments.length ? (parentId = required(x), stratify) : parentId;
29635   };
29636
29637   return stratify;
29638 };
29639
29640 function defaultSeparation$1(a, b) {
29641   return a.parent === b.parent ? 1 : 2;
29642 }
29643
29644 // function radialSeparation(a, b) {
29645 //   return (a.parent === b.parent ? 1 : 2) / a.depth;
29646 // }
29647
29648 // This function is used to traverse the left contour of a subtree (or
29649 // subforest). It returns the successor of v on this contour. This successor is
29650 // either given by the leftmost child of v or by the thread of v. The function
29651 // returns null if and only if v is on the highest level of its subtree.
29652 function nextLeft(v) {
29653   var children = v.children;
29654   return children ? children[0] : v.t;
29655 }
29656
29657 // This function works analogously to nextLeft.
29658 function nextRight(v) {
29659   var children = v.children;
29660   return children ? children[children.length - 1] : v.t;
29661 }
29662
29663 // Shifts the current subtree rooted at w+. This is done by increasing
29664 // prelim(w+) and mod(w+) by shift.
29665 function moveSubtree(wm, wp, shift) {
29666   var change = shift / (wp.i - wm.i);
29667   wp.c -= change;
29668   wp.s += shift;
29669   wm.c += change;
29670   wp.z += shift;
29671   wp.m += shift;
29672 }
29673
29674 // All other shifts, applied to the smaller subtrees between w- and w+, are
29675 // performed by this function. To prepare the shifts, we have to adjust
29676 // change(w+), shift(w+), and change(w-).
29677 function executeShifts(v) {
29678   var shift = 0,
29679       change = 0,
29680       children = v.children,
29681       i = children.length,
29682       w;
29683   while (--i >= 0) {
29684     w = children[i];
29685     w.z += shift;
29686     w.m += shift;
29687     shift += w.s + (change += w.c);
29688   }
29689 }
29690
29691 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
29692 // returns the specified (default) ancestor.
29693 function nextAncestor(vim, v, ancestor) {
29694   return vim.a.parent === v.parent ? vim.a : ancestor;
29695 }
29696
29697 function TreeNode(node, i) {
29698   this._ = node;
29699   this.parent = null;
29700   this.children = null;
29701   this.A = null; // default ancestor
29702   this.a = this; // ancestor
29703   this.z = 0; // prelim
29704   this.m = 0; // mod
29705   this.c = 0; // change
29706   this.s = 0; // shift
29707   this.t = null; // thread
29708   this.i = i; // number
29709 }
29710
29711 TreeNode.prototype = Object.create(Node.prototype);
29712
29713 function treeRoot(root) {
29714   var tree = new TreeNode(root, 0),
29715       node,
29716       nodes = [tree],
29717       child,
29718       children,
29719       i,
29720       n;
29721
29722   while (node = nodes.pop()) {
29723     if (children = node._.children) {
29724       node.children = new Array(n = children.length);
29725       for (i = n - 1; i >= 0; --i) {
29726         nodes.push(child = node.children[i] = new TreeNode(children[i], i));
29727         child.parent = node;
29728       }
29729     }
29730   }
29731
29732   (tree.parent = new TreeNode(null, 0)).children = [tree];
29733   return tree;
29734 }
29735
29736 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
29737 var tree = function() {
29738   var separation = defaultSeparation$1,
29739       dx = 1,
29740       dy = 1,
29741       nodeSize = null;
29742
29743   function tree(root) {
29744     var t = treeRoot(root);
29745
29746     // Compute the layout using Buchheim et al.’s algorithm.
29747     t.eachAfter(firstWalk), t.parent.m = -t.z;
29748     t.eachBefore(secondWalk);
29749
29750     // If a fixed node size is specified, scale x and y.
29751     if (nodeSize) root.eachBefore(sizeNode);
29752
29753     // If a fixed tree size is specified, scale x and y based on the extent.
29754     // Compute the left-most, right-most, and depth-most nodes for extents.
29755     else {
29756       var left = root,
29757           right = root,
29758           bottom = root;
29759       root.eachBefore(function(node) {
29760         if (node.x < left.x) left = node;
29761         if (node.x > right.x) right = node;
29762         if (node.depth > bottom.depth) bottom = node;
29763       });
29764       var s = left === right ? 1 : separation(left, right) / 2,
29765           tx = s - left.x,
29766           kx = dx / (right.x + s + tx),
29767           ky = dy / (bottom.depth || 1);
29768       root.eachBefore(function(node) {
29769         node.x = (node.x + tx) * kx;
29770         node.y = node.depth * ky;
29771       });
29772     }
29773
29774     return root;
29775   }
29776
29777   // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
29778   // applied recursively to the children of v, as well as the function
29779   // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
29780   // node v is placed to the midpoint of its outermost children.
29781   function firstWalk(v) {
29782     var children = v.children,
29783         siblings = v.parent.children,
29784         w = v.i ? siblings[v.i - 1] : null;
29785     if (children) {
29786       executeShifts(v);
29787       var midpoint = (children[0].z + children[children.length - 1].z) / 2;
29788       if (w) {
29789         v.z = w.z + separation(v._, w._);
29790         v.m = v.z - midpoint;
29791       } else {
29792         v.z = midpoint;
29793       }
29794     } else if (w) {
29795       v.z = w.z + separation(v._, w._);
29796     }
29797     v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
29798   }
29799
29800   // Computes all real x-coordinates by summing up the modifiers recursively.
29801   function secondWalk(v) {
29802     v._.x = v.z + v.parent.m;
29803     v.m += v.parent.m;
29804   }
29805
29806   // The core of the algorithm. Here, a new subtree is combined with the
29807   // previous subtrees. Threads are used to traverse the inside and outside
29808   // contours of the left and right subtree up to the highest common level. The
29809   // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
29810   // superscript o means outside and i means inside, the subscript - means left
29811   // subtree and + means right subtree. For summing up the modifiers along the
29812   // contour, we use respective variables si+, si-, so-, and so+. Whenever two
29813   // nodes of the inside contours conflict, we compute the left one of the
29814   // greatest uncommon ancestors using the function ANCESTOR and call MOVE
29815   // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
29816   // Finally, we add a new thread (if necessary).
29817   function apportion(v, w, ancestor) {
29818     if (w) {
29819       var vip = v,
29820           vop = v,
29821           vim = w,
29822           vom = vip.parent.children[0],
29823           sip = vip.m,
29824           sop = vop.m,
29825           sim = vim.m,
29826           som = vom.m,
29827           shift;
29828       while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
29829         vom = nextLeft(vom);
29830         vop = nextRight(vop);
29831         vop.a = v;
29832         shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
29833         if (shift > 0) {
29834           moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
29835           sip += shift;
29836           sop += shift;
29837         }
29838         sim += vim.m;
29839         sip += vip.m;
29840         som += vom.m;
29841         sop += vop.m;
29842       }
29843       if (vim && !nextRight(vop)) {
29844         vop.t = vim;
29845         vop.m += sim - sop;
29846       }
29847       if (vip && !nextLeft(vom)) {
29848         vom.t = vip;
29849         vom.m += sip - som;
29850         ancestor = v;
29851       }
29852     }
29853     return ancestor;
29854   }
29855
29856   function sizeNode(node) {
29857     node.x *= dx;
29858     node.y = node.depth * dy;
29859   }
29860
29861   tree.separation = function(x) {
29862     return arguments.length ? (separation = x, tree) : separation;
29863   };
29864
29865   tree.size = function(x) {
29866     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
29867   };
29868
29869   tree.nodeSize = function(x) {
29870     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
29871   };
29872
29873   return tree;
29874 };
29875
29876 var treemapSlice = function(parent, x0, y0, x1, y1) {
29877   var nodes = parent.children,
29878       node,
29879       i = -1,
29880       n = nodes.length,
29881       k = parent.value && (y1 - y0) / parent.value;
29882
29883   while (++i < n) {
29884     node = nodes[i], node.x0 = x0, node.x1 = x1;
29885     node.y0 = y0, node.y1 = y0 += node.value * k;
29886   }
29887 };
29888
29889 var phi = (1 + Math.sqrt(5)) / 2;
29890
29891 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
29892   var rows = [],
29893       nodes = parent.children,
29894       row,
29895       nodeValue,
29896       i0 = 0,
29897       i1 = 0,
29898       n = nodes.length,
29899       dx, dy,
29900       value = parent.value,
29901       sumValue,
29902       minValue,
29903       maxValue,
29904       newRatio,
29905       minRatio,
29906       alpha,
29907       beta;
29908
29909   while (i0 < n) {
29910     dx = x1 - x0, dy = y1 - y0;
29911
29912     // Find the next non-empty node.
29913     do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
29914     minValue = maxValue = sumValue;
29915     alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
29916     beta = sumValue * sumValue * alpha;
29917     minRatio = Math.max(maxValue / beta, beta / minValue);
29918
29919     // Keep adding nodes while the aspect ratio maintains or improves.
29920     for (; i1 < n; ++i1) {
29921       sumValue += nodeValue = nodes[i1].value;
29922       if (nodeValue < minValue) minValue = nodeValue;
29923       if (nodeValue > maxValue) maxValue = nodeValue;
29924       beta = sumValue * sumValue * alpha;
29925       newRatio = Math.max(maxValue / beta, beta / minValue);
29926       if (newRatio > minRatio) { sumValue -= nodeValue; break; }
29927       minRatio = newRatio;
29928     }
29929
29930     // Position and record the row orientation.
29931     rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
29932     if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
29933     else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
29934     value -= sumValue, i0 = i1;
29935   }
29936
29937   return rows;
29938 }
29939
29940 var squarify = (function custom(ratio) {
29941
29942   function squarify(parent, x0, y0, x1, y1) {
29943     squarifyRatio(ratio, parent, x0, y0, x1, y1);
29944   }
29945
29946   squarify.ratio = function(x) {
29947     return custom((x = +x) > 1 ? x : 1);
29948   };
29949
29950   return squarify;
29951 })(phi);
29952
29953 var index$6 = function() {
29954   var tile = squarify,
29955       round = false,
29956       dx = 1,
29957       dy = 1,
29958       paddingStack = [0],
29959       paddingInner = constantZero,
29960       paddingTop = constantZero,
29961       paddingRight = constantZero,
29962       paddingBottom = constantZero,
29963       paddingLeft = constantZero;
29964
29965   function treemap(root) {
29966     root.x0 =
29967     root.y0 = 0;
29968     root.x1 = dx;
29969     root.y1 = dy;
29970     root.eachBefore(positionNode);
29971     paddingStack = [0];
29972     if (round) root.eachBefore(roundNode);
29973     return root;
29974   }
29975
29976   function positionNode(node) {
29977     var p = paddingStack[node.depth],
29978         x0 = node.x0 + p,
29979         y0 = node.y0 + p,
29980         x1 = node.x1 - p,
29981         y1 = node.y1 - p;
29982     if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29983     if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29984     node.x0 = x0;
29985     node.y0 = y0;
29986     node.x1 = x1;
29987     node.y1 = y1;
29988     if (node.children) {
29989       p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
29990       x0 += paddingLeft(node) - p;
29991       y0 += paddingTop(node) - p;
29992       x1 -= paddingRight(node) - p;
29993       y1 -= paddingBottom(node) - p;
29994       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29995       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29996       tile(node, x0, y0, x1, y1);
29997     }
29998   }
29999
30000   treemap.round = function(x) {
30001     return arguments.length ? (round = !!x, treemap) : round;
30002   };
30003
30004   treemap.size = function(x) {
30005     return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
30006   };
30007
30008   treemap.tile = function(x) {
30009     return arguments.length ? (tile = required(x), treemap) : tile;
30010   };
30011
30012   treemap.padding = function(x) {
30013     return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
30014   };
30015
30016   treemap.paddingInner = function(x) {
30017     return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner;
30018   };
30019
30020   treemap.paddingOuter = function(x) {
30021     return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
30022   };
30023
30024   treemap.paddingTop = function(x) {
30025     return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop;
30026   };
30027
30028   treemap.paddingRight = function(x) {
30029     return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight;
30030   };
30031
30032   treemap.paddingBottom = function(x) {
30033     return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom;
30034   };
30035
30036   treemap.paddingLeft = function(x) {
30037     return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft;
30038   };
30039
30040   return treemap;
30041 };
30042
30043 var binary = function(parent, x0, y0, x1, y1) {
30044   var nodes = parent.children,
30045       i, n = nodes.length,
30046       sum, sums = new Array(n + 1);
30047
30048   for (sums[0] = sum = i = 0; i < n; ++i) {
30049     sums[i + 1] = sum += nodes[i].value;
30050   }
30051
30052   partition(0, n, parent.value, x0, y0, x1, y1);
30053
30054   function partition(i, j, value, x0, y0, x1, y1) {
30055     if (i >= j - 1) {
30056       var node = nodes[i];
30057       node.x0 = x0, node.y0 = y0;
30058       node.x1 = x1, node.y1 = y1;
30059       return;
30060     }
30061
30062     var valueOffset = sums[i],
30063         valueTarget = (value / 2) + valueOffset,
30064         k = i + 1,
30065         hi = j - 1;
30066
30067     while (k < hi) {
30068       var mid = k + hi >>> 1;
30069       if (sums[mid] < valueTarget) k = mid + 1;
30070       else hi = mid;
30071     }
30072
30073     if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
30074
30075     var valueLeft = sums[k] - valueOffset,
30076         valueRight = value - valueLeft;
30077
30078     if ((x1 - x0) > (y1 - y0)) {
30079       var xk = (x0 * valueRight + x1 * valueLeft) / value;
30080       partition(i, k, valueLeft, x0, y0, xk, y1);
30081       partition(k, j, valueRight, xk, y0, x1, y1);
30082     } else {
30083       var yk = (y0 * valueRight + y1 * valueLeft) / value;
30084       partition(i, k, valueLeft, x0, y0, x1, yk);
30085       partition(k, j, valueRight, x0, yk, x1, y1);
30086     }
30087   }
30088 };
30089
30090 var sliceDice = function(parent, x0, y0, x1, y1) {
30091   (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
30092 };
30093
30094 var resquarify = (function custom(ratio) {
30095
30096   function resquarify(parent, x0, y0, x1, y1) {
30097     if ((rows = parent._squarify) && (rows.ratio === ratio)) {
30098       var rows,
30099           row,
30100           nodes,
30101           i,
30102           j = -1,
30103           n,
30104           m = rows.length,
30105           value = parent.value;
30106
30107       while (++j < m) {
30108         row = rows[j], nodes = row.children;
30109         for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
30110         if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
30111         else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
30112         value -= row.value;
30113       }
30114     } else {
30115       parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
30116       rows.ratio = ratio;
30117     }
30118   }
30119
30120   resquarify.ratio = function(x) {
30121     return custom((x = +x) > 1 ? x : 1);
30122   };
30123
30124   return resquarify;
30125 })(phi);
30126
30127 var d3polygonArea = function(polygon) {
30128   var i = -1,
30129       n = polygon.length,
30130       a,
30131       b = polygon[n - 1],
30132       area = 0;
30133
30134   while (++i < n) {
30135     a = b;
30136     b = polygon[i];
30137     area += a[1] * b[0] - a[0] * b[1];
30138   }
30139
30140   return area / 2;
30141 };
30142
30143 var d3polygonCentroid = function(polygon) {
30144   var i = -1,
30145       n = polygon.length,
30146       x = 0,
30147       y = 0,
30148       a,
30149       b = polygon[n - 1],
30150       c,
30151       k = 0;
30152
30153   while (++i < n) {
30154     a = b;
30155     b = polygon[i];
30156     k += c = a[0] * b[1] - b[0] * a[1];
30157     x += (a[0] + b[0]) * c;
30158     y += (a[1] + b[1]) * c;
30159   }
30160
30161   return k *= 3, [x / k, y / k];
30162 };
30163
30164 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
30165 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
30166 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
30167 // negative if clockwise, and zero if the points are collinear.
30168 var cross$1 = function(a, b, c) {
30169   return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
30170 };
30171
30172 function lexicographicOrder(a, b) {
30173   return a[0] - b[0] || a[1] - b[1];
30174 }
30175
30176 // Computes the upper convex hull per the monotone chain algorithm.
30177 // Assumes points.length >= 3, is sorted by x, unique in y.
30178 // Returns an array of indices into points in left-to-right order.
30179 function computeUpperHullIndexes(points) {
30180   var n = points.length,
30181       indexes = [0, 1],
30182       size = 2;
30183
30184   for (var i = 2; i < n; ++i) {
30185     while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
30186     indexes[size++] = i;
30187   }
30188
30189   return indexes.slice(0, size); // remove popped points
30190 }
30191
30192 var d3polygonHull = function(points) {
30193   if ((n = points.length) < 3) return null;
30194
30195   var i,
30196       n,
30197       sortedPoints = new Array(n),
30198       flippedPoints = new Array(n);
30199
30200   for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
30201   sortedPoints.sort(lexicographicOrder);
30202   for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
30203
30204   var upperIndexes = computeUpperHullIndexes(sortedPoints),
30205       lowerIndexes = computeUpperHullIndexes(flippedPoints);
30206
30207   // Construct the hull polygon, removing possible duplicate endpoints.
30208   var skipLeft = lowerIndexes[0] === upperIndexes[0],
30209       skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
30210       hull = [];
30211
30212   // Add upper hull in right-to-l order.
30213   // Then add lower hull in left-to-right order.
30214   for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
30215   for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
30216
30217   return hull;
30218 };
30219
30220 var contains$1 = function(polygon, point) {
30221   var n = polygon.length,
30222       p = polygon[n - 1],
30223       x = point[0], y = point[1],
30224       x0 = p[0], y0 = p[1],
30225       x1, y1,
30226       inside = false;
30227
30228   for (var i = 0; i < n; ++i) {
30229     p = polygon[i], x1 = p[0], y1 = p[1];
30230     if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
30231     x0 = x1, y0 = y1;
30232   }
30233
30234   return inside;
30235 };
30236
30237 var length$1 = function(polygon) {
30238   var i = -1,
30239       n = polygon.length,
30240       b = polygon[n - 1],
30241       xa,
30242       ya,
30243       xb = b[0],
30244       yb = b[1],
30245       perimeter = 0;
30246
30247   while (++i < n) {
30248     xa = xb;
30249     ya = yb;
30250     b = polygon[i];
30251     xb = b[0];
30252     yb = b[1];
30253     xa -= xb;
30254     ya -= yb;
30255     perimeter += Math.sqrt(xa * xa + ya * ya);
30256   }
30257
30258   return perimeter;
30259 };
30260
30261 var slice$4 = [].slice;
30262
30263 var noabort = {};
30264
30265 function Queue(size) {
30266   this._size = size;
30267   this._call =
30268   this._error = null;
30269   this._tasks = [];
30270   this._data = [];
30271   this._waiting =
30272   this._active =
30273   this._ended =
30274   this._start = 0; // inside a synchronous task callback?
30275 }
30276
30277 Queue.prototype = queue.prototype = {
30278   constructor: Queue,
30279   defer: function(callback) {
30280     if (typeof callback !== "function") throw new Error("invalid callback");
30281     if (this._call) throw new Error("defer after await");
30282     if (this._error != null) return this;
30283     var t = slice$4.call(arguments, 1);
30284     t.push(callback);
30285     ++this._waiting, this._tasks.push(t);
30286     poke$1(this);
30287     return this;
30288   },
30289   abort: function() {
30290     if (this._error == null) abort(this, new Error("abort"));
30291     return this;
30292   },
30293   await: function(callback) {
30294     if (typeof callback !== "function") throw new Error("invalid callback");
30295     if (this._call) throw new Error("multiple await");
30296     this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
30297     maybeNotify(this);
30298     return this;
30299   },
30300   awaitAll: function(callback) {
30301     if (typeof callback !== "function") throw new Error("invalid callback");
30302     if (this._call) throw new Error("multiple await");
30303     this._call = callback;
30304     maybeNotify(this);
30305     return this;
30306   }
30307 };
30308
30309 function poke$1(q) {
30310   if (!q._start) {
30311     try { start$1(q); } // let the current task complete
30312     catch (e) {
30313       if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
30314       else if (!q._data) throw e; // await callback errored synchronously
30315     }
30316   }
30317 }
30318
30319 function start$1(q) {
30320   while (q._start = q._waiting && q._active < q._size) {
30321     var i = q._ended + q._active,
30322         t = q._tasks[i],
30323         j = t.length - 1,
30324         c = t[j];
30325     t[j] = end(q, i);
30326     --q._waiting, ++q._active;
30327     t = c.apply(null, t);
30328     if (!q._tasks[i]) continue; // task finished synchronously
30329     q._tasks[i] = t || noabort;
30330   }
30331 }
30332
30333 function end(q, i) {
30334   return function(e, r) {
30335     if (!q._tasks[i]) return; // ignore multiple callbacks
30336     --q._active, ++q._ended;
30337     q._tasks[i] = null;
30338     if (q._error != null) return; // ignore secondary errors
30339     if (e != null) {
30340       abort(q, e);
30341     } else {
30342       q._data[i] = r;
30343       if (q._waiting) poke$1(q);
30344       else maybeNotify(q);
30345     }
30346   };
30347 }
30348
30349 function abort(q, e) {
30350   var i = q._tasks.length, t;
30351   q._error = e; // ignore active callbacks
30352   q._data = undefined; // allow gc
30353   q._waiting = NaN; // prevent starting
30354
30355   while (--i >= 0) {
30356     if (t = q._tasks[i]) {
30357       q._tasks[i] = null;
30358       if (t.abort) {
30359         try { t.abort(); }
30360         catch (e) { /* ignore */ }
30361       }
30362     }
30363   }
30364
30365   q._active = NaN; // allow notification
30366   maybeNotify(q);
30367 }
30368
30369 function maybeNotify(q) {
30370   if (!q._active && q._call) {
30371     var d = q._data;
30372     q._data = undefined; // allow gc
30373     q._call(q._error, d);
30374   }
30375 }
30376
30377 function queue(concurrency) {
30378   if (concurrency == null) concurrency = Infinity;
30379   else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency");
30380   return new Queue(concurrency);
30381 }
30382
30383 var defaultSource$1 = function() {
30384   return Math.random();
30385 };
30386
30387 var uniform = (function sourceRandomUniform(source) {
30388   function randomUniform(min, max) {
30389     min = min == null ? 0 : +min;
30390     max = max == null ? 1 : +max;
30391     if (arguments.length === 1) max = min, min = 0;
30392     else max -= min;
30393     return function() {
30394       return source() * max + min;
30395     };
30396   }
30397
30398   randomUniform.source = sourceRandomUniform;
30399
30400   return randomUniform;
30401 })(defaultSource$1);
30402
30403 var normal = (function sourceRandomNormal(source) {
30404   function randomNormal(mu, sigma) {
30405     var x, r;
30406     mu = mu == null ? 0 : +mu;
30407     sigma = sigma == null ? 1 : +sigma;
30408     return function() {
30409       var y;
30410
30411       // If available, use the second previously-generated uniform random.
30412       if (x != null) y = x, x = null;
30413
30414       // Otherwise, generate a new x and y.
30415       else do {
30416         x = source() * 2 - 1;
30417         y = source() * 2 - 1;
30418         r = x * x + y * y;
30419       } while (!r || r > 1);
30420
30421       return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
30422     };
30423   }
30424
30425   randomNormal.source = sourceRandomNormal;
30426
30427   return randomNormal;
30428 })(defaultSource$1);
30429
30430 var logNormal = (function sourceRandomLogNormal(source) {
30431   function randomLogNormal() {
30432     var randomNormal = normal.source(source).apply(this, arguments);
30433     return function() {
30434       return Math.exp(randomNormal());
30435     };
30436   }
30437
30438   randomLogNormal.source = sourceRandomLogNormal;
30439
30440   return randomLogNormal;
30441 })(defaultSource$1);
30442
30443 var irwinHall = (function sourceRandomIrwinHall(source) {
30444   function randomIrwinHall(n) {
30445     return function() {
30446       for (var sum = 0, i = 0; i < n; ++i) sum += source();
30447       return sum;
30448     };
30449   }
30450
30451   randomIrwinHall.source = sourceRandomIrwinHall;
30452
30453   return randomIrwinHall;
30454 })(defaultSource$1);
30455
30456 var bates = (function sourceRandomBates(source) {
30457   function randomBates(n) {
30458     var randomIrwinHall = irwinHall.source(source)(n);
30459     return function() {
30460       return randomIrwinHall() / n;
30461     };
30462   }
30463
30464   randomBates.source = sourceRandomBates;
30465
30466   return randomBates;
30467 })(defaultSource$1);
30468
30469 var exponential$1 = (function sourceRandomExponential(source) {
30470   function randomExponential(lambda) {
30471     return function() {
30472       return -Math.log(1 - source()) / lambda;
30473     };
30474   }
30475
30476   randomExponential.source = sourceRandomExponential;
30477
30478   return randomExponential;
30479 })(defaultSource$1);
30480
30481 var request = function(url, callback) {
30482   var request,
30483       event = dispatch("beforesend", "progress", "load", "error"),
30484       mimeType,
30485       headers = map$1(),
30486       xhr = new XMLHttpRequest,
30487       user = null,
30488       password = null,
30489       response,
30490       responseType,
30491       timeout = 0;
30492
30493   // If IE does not support CORS, use XDomainRequest.
30494   if (typeof XDomainRequest !== "undefined"
30495       && !("withCredentials" in xhr)
30496       && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
30497
30498   "onload" in xhr
30499       ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
30500       : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
30501
30502   function respond(o) {
30503     var status = xhr.status, result;
30504     if (!status && hasResponse(xhr)
30505         || status >= 200 && status < 300
30506         || status === 304) {
30507       if (response) {
30508         try {
30509           result = response.call(request, xhr);
30510         } catch (e) {
30511           event.call("error", request, e);
30512           return;
30513         }
30514       } else {
30515         result = xhr;
30516       }
30517       event.call("load", request, result);
30518     } else {
30519       event.call("error", request, o);
30520     }
30521   }
30522
30523   xhr.onprogress = function(e) {
30524     event.call("progress", request, e);
30525   };
30526
30527   request = {
30528     header: function(name, value) {
30529       name = (name + "").toLowerCase();
30530       if (arguments.length < 2) return headers.get(name);
30531       if (value == null) headers.remove(name);
30532       else headers.set(name, value + "");
30533       return request;
30534     },
30535
30536     // If mimeType is non-null and no Accept header is set, a default is used.
30537     mimeType: function(value) {
30538       if (!arguments.length) return mimeType;
30539       mimeType = value == null ? null : value + "";
30540       return request;
30541     },
30542
30543     // Specifies what type the response value should take;
30544     // for instance, arraybuffer, blob, document, or text.
30545     responseType: function(value) {
30546       if (!arguments.length) return responseType;
30547       responseType = value;
30548       return request;
30549     },
30550
30551     timeout: function(value) {
30552       if (!arguments.length) return timeout;
30553       timeout = +value;
30554       return request;
30555     },
30556
30557     user: function(value) {
30558       return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
30559     },
30560
30561     password: function(value) {
30562       return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
30563     },
30564
30565     // Specify how to convert the response content to a specific type;
30566     // changes the callback value on "load" events.
30567     response: function(value) {
30568       response = value;
30569       return request;
30570     },
30571
30572     // Alias for send("GET", …).
30573     get: function(data, callback) {
30574       return request.send("GET", data, callback);
30575     },
30576
30577     // Alias for send("POST", …).
30578     post: function(data, callback) {
30579       return request.send("POST", data, callback);
30580     },
30581
30582     // If callback is non-null, it will be used for error and load events.
30583     send: function(method, data, callback) {
30584       xhr.open(method, url, true, user, password);
30585       if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
30586       if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
30587       if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
30588       if (responseType != null) xhr.responseType = responseType;
30589       if (timeout > 0) xhr.timeout = timeout;
30590       if (callback == null && typeof data === "function") callback = data, data = null;
30591       if (callback != null && callback.length === 1) callback = fixCallback(callback);
30592       if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
30593       event.call("beforesend", request, xhr);
30594       xhr.send(data == null ? null : data);
30595       return request;
30596     },
30597
30598     abort: function() {
30599       xhr.abort();
30600       return request;
30601     },
30602
30603     on: function() {
30604       var value = event.on.apply(event, arguments);
30605       return value === event ? request : value;
30606     }
30607   };
30608
30609   if (callback != null) {
30610     if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
30611     return request.get(callback);
30612   }
30613
30614   return request;
30615 };
30616
30617 function fixCallback(callback) {
30618   return function(error, xhr) {
30619     callback(error == null ? xhr : null);
30620   };
30621 }
30622
30623 function hasResponse(xhr) {
30624   var type = xhr.responseType;
30625   return type && type !== "text"
30626       ? xhr.response // null on error
30627       : xhr.responseText; // "" on error
30628 }
30629
30630 var type$3 = function(defaultMimeType, response) {
30631   return function(url, callback) {
30632     var r = request(url).mimeType(defaultMimeType).response(response);
30633     if (callback != null) {
30634       if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
30635       return r.get(callback);
30636     }
30637     return r;
30638   };
30639 };
30640
30641 var html = type$3("text/html", function(xhr) {
30642   return document.createRange().createContextualFragment(xhr.responseText);
30643 });
30644
30645 var json = type$3("application/json", function(xhr) {
30646   return JSON.parse(xhr.responseText);
30647 });
30648
30649 var text = type$3("text/plain", function(xhr) {
30650   return xhr.responseText;
30651 });
30652
30653 var xml = type$3("application/xml", function(xhr) {
30654   var xml = xhr.responseXML;
30655   if (!xml) throw new Error("parse error");
30656   return xml;
30657 });
30658
30659 var dsv$1 = function(defaultMimeType, parse) {
30660   return function(url, row, callback) {
30661     if (arguments.length < 3) callback = row, row = null;
30662     var r = request(url).mimeType(defaultMimeType);
30663     r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
30664     r.row(row);
30665     return callback ? r.get(callback) : r;
30666   };
30667 };
30668
30669 function responseOf(parse, row) {
30670   return function(request$$1) {
30671     return parse(request$$1.responseText, row);
30672   };
30673 }
30674
30675 var csv$1 = dsv$1("text/csv", csvParse);
30676
30677 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
30678
30679 var array$2 = Array.prototype;
30680
30681 var map$3 = array$2.map;
30682 var slice$5 = array$2.slice;
30683
30684 var implicit = {name: "implicit"};
30685
30686 function ordinal(range) {
30687   var index = map$1(),
30688       domain = [],
30689       unknown = implicit;
30690
30691   range = range == null ? [] : slice$5.call(range);
30692
30693   function scale(d) {
30694     var key = d + "", i = index.get(key);
30695     if (!i) {
30696       if (unknown !== implicit) return unknown;
30697       index.set(key, i = domain.push(d));
30698     }
30699     return range[(i - 1) % range.length];
30700   }
30701
30702   scale.domain = function(_) {
30703     if (!arguments.length) return domain.slice();
30704     domain = [], index = map$1();
30705     var i = -1, n = _.length, d, key;
30706     while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
30707     return scale;
30708   };
30709
30710   scale.range = function(_) {
30711     return arguments.length ? (range = slice$5.call(_), scale) : range.slice();
30712   };
30713
30714   scale.unknown = function(_) {
30715     return arguments.length ? (unknown = _, scale) : unknown;
30716   };
30717
30718   scale.copy = function() {
30719     return ordinal()
30720         .domain(domain)
30721         .range(range)
30722         .unknown(unknown);
30723   };
30724
30725   return scale;
30726 }
30727
30728 function band() {
30729   var scale = ordinal().unknown(undefined),
30730       domain = scale.domain,
30731       ordinalRange = scale.range,
30732       range = [0, 1],
30733       step,
30734       bandwidth,
30735       round = false,
30736       paddingInner = 0,
30737       paddingOuter = 0,
30738       align = 0.5;
30739
30740   delete scale.unknown;
30741
30742   function rescale() {
30743     var n = domain().length,
30744         reverse = range[1] < range[0],
30745         start = range[reverse - 0],
30746         stop = range[1 - reverse];
30747     step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
30748     if (round) step = Math.floor(step);
30749     start += (stop - start - step * (n - paddingInner)) * align;
30750     bandwidth = step * (1 - paddingInner);
30751     if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
30752     var values = sequence(n).map(function(i) { return start + step * i; });
30753     return ordinalRange(reverse ? values.reverse() : values);
30754   }
30755
30756   scale.domain = function(_) {
30757     return arguments.length ? (domain(_), rescale()) : domain();
30758   };
30759
30760   scale.range = function(_) {
30761     return arguments.length ? (range = [+_[0], +_[1]], rescale()) : range.slice();
30762   };
30763
30764   scale.rangeRound = function(_) {
30765     return range = [+_[0], +_[1]], round = true, rescale();
30766   };
30767
30768   scale.bandwidth = function() {
30769     return bandwidth;
30770   };
30771
30772   scale.step = function() {
30773     return step;
30774   };
30775
30776   scale.round = function(_) {
30777     return arguments.length ? (round = !!_, rescale()) : round;
30778   };
30779
30780   scale.padding = function(_) {
30781     return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
30782   };
30783
30784   scale.paddingInner = function(_) {
30785     return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
30786   };
30787
30788   scale.paddingOuter = function(_) {
30789     return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
30790   };
30791
30792   scale.align = function(_) {
30793     return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
30794   };
30795
30796   scale.copy = function() {
30797     return band()
30798         .domain(domain())
30799         .range(range)
30800         .round(round)
30801         .paddingInner(paddingInner)
30802         .paddingOuter(paddingOuter)
30803         .align(align);
30804   };
30805
30806   return rescale();
30807 }
30808
30809 function pointish(scale) {
30810   var copy = scale.copy;
30811
30812   scale.padding = scale.paddingOuter;
30813   delete scale.paddingInner;
30814   delete scale.paddingOuter;
30815
30816   scale.copy = function() {
30817     return pointish(copy());
30818   };
30819
30820   return scale;
30821 }
30822
30823 function point$1() {
30824   return pointish(band().paddingInner(1));
30825 }
30826
30827 var constant$9 = function(x) {
30828   return function() {
30829     return x;
30830   };
30831 };
30832
30833 var number$2 = function(x) {
30834   return +x;
30835 };
30836
30837 var unit = [0, 1];
30838
30839 function deinterpolateLinear(a, b) {
30840   return (b -= (a = +a))
30841       ? function(x) { return (x - a) / b; }
30842       : constant$9(b);
30843 }
30844
30845 function deinterpolateClamp(deinterpolate) {
30846   return function(a, b) {
30847     var d = deinterpolate(a = +a, b = +b);
30848     return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
30849   };
30850 }
30851
30852 function reinterpolateClamp(reinterpolate$$1) {
30853   return function(a, b) {
30854     var r = reinterpolate$$1(a = +a, b = +b);
30855     return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
30856   };
30857 }
30858
30859 function bimap(domain, range, deinterpolate, reinterpolate$$1) {
30860   var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
30861   if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate$$1(r1, r0);
30862   else d0 = deinterpolate(d0, d1), r0 = reinterpolate$$1(r0, r1);
30863   return function(x) { return r0(d0(x)); };
30864 }
30865
30866 function polymap(domain, range, deinterpolate, reinterpolate$$1) {
30867   var j = Math.min(domain.length, range.length) - 1,
30868       d = new Array(j),
30869       r = new Array(j),
30870       i = -1;
30871
30872   // Reverse descending domains.
30873   if (domain[j] < domain[0]) {
30874     domain = domain.slice().reverse();
30875     range = range.slice().reverse();
30876   }
30877
30878   while (++i < j) {
30879     d[i] = deinterpolate(domain[i], domain[i + 1]);
30880     r[i] = reinterpolate$$1(range[i], range[i + 1]);
30881   }
30882
30883   return function(x) {
30884     var i = bisectRight(domain, x, 1, j) - 1;
30885     return r[i](d[i](x));
30886   };
30887 }
30888
30889 function copy(source, target) {
30890   return target
30891       .domain(source.domain())
30892       .range(source.range())
30893       .interpolate(source.interpolate())
30894       .clamp(source.clamp());
30895 }
30896
30897 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
30898 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
30899 function continuous(deinterpolate, reinterpolate$$1) {
30900   var domain = unit,
30901       range = unit,
30902       interpolate = interpolateValue,
30903       clamp = false,
30904       piecewise,
30905       output,
30906       input;
30907
30908   function rescale() {
30909     piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;
30910     output = input = null;
30911     return scale;
30912   }
30913
30914   function scale(x) {
30915     return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate)))(+x);
30916   }
30917
30918   scale.invert = function(y) {
30919     return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate$$1) : reinterpolate$$1)))(+y);
30920   };
30921
30922   scale.domain = function(_) {
30923     return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();
30924   };
30925
30926   scale.range = function(_) {
30927     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
30928   };
30929
30930   scale.rangeRound = function(_) {
30931     return range = slice$5.call(_), interpolate = interpolateRound, rescale();
30932   };
30933
30934   scale.clamp = function(_) {
30935     return arguments.length ? (clamp = !!_, rescale()) : clamp;
30936   };
30937
30938   scale.interpolate = function(_) {
30939     return arguments.length ? (interpolate = _, rescale()) : interpolate;
30940   };
30941
30942   return rescale();
30943 }
30944
30945 var tickFormat = function(domain, count, specifier) {
30946   var start = domain[0],
30947       stop = domain[domain.length - 1],
30948       step = tickStep(start, stop, count == null ? 10 : count),
30949       precision;
30950   specifier = formatSpecifier(specifier == null ? ",f" : specifier);
30951   switch (specifier.type) {
30952     case "s": {
30953       var value = Math.max(Math.abs(start), Math.abs(stop));
30954       if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
30955       return formatPrefix(specifier, value);
30956     }
30957     case "":
30958     case "e":
30959     case "g":
30960     case "p":
30961     case "r": {
30962       if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
30963       break;
30964     }
30965     case "f":
30966     case "%": {
30967       if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
30968       break;
30969     }
30970   }
30971   return format(specifier);
30972 };
30973
30974 function linearish(scale) {
30975   var domain = scale.domain;
30976
30977   scale.ticks = function(count) {
30978     var d = domain();
30979     return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
30980   };
30981
30982   scale.tickFormat = function(count, specifier) {
30983     return tickFormat(domain(), count, specifier);
30984   };
30985
30986   scale.nice = function(count) {
30987     if (count == null) count = 10;
30988
30989     var d = domain(),
30990         i0 = 0,
30991         i1 = d.length - 1,
30992         start = d[i0],
30993         stop = d[i1],
30994         step;
30995
30996     if (stop < start) {
30997       step = start, start = stop, stop = step;
30998       step = i0, i0 = i1, i1 = step;
30999     }
31000
31001     step = tickIncrement(start, stop, count);
31002
31003     if (step > 0) {
31004       start = Math.floor(start / step) * step;
31005       stop = Math.ceil(stop / step) * step;
31006       step = tickIncrement(start, stop, count);
31007     } else if (step < 0) {
31008       start = Math.ceil(start * step) / step;
31009       stop = Math.floor(stop * step) / step;
31010       step = tickIncrement(start, stop, count);
31011     }
31012
31013     if (step > 0) {
31014       d[i0] = Math.floor(start / step) * step;
31015       d[i1] = Math.ceil(stop / step) * step;
31016       domain(d);
31017     } else if (step < 0) {
31018       d[i0] = Math.ceil(start * step) / step;
31019       d[i1] = Math.floor(stop * step) / step;
31020       domain(d);
31021     }
31022
31023     return scale;
31024   };
31025
31026   return scale;
31027 }
31028
31029 function linear$2() {
31030   var scale = continuous(deinterpolateLinear, reinterpolate);
31031
31032   scale.copy = function() {
31033     return copy(scale, linear$2());
31034   };
31035
31036   return linearish(scale);
31037 }
31038
31039 function identity$6() {
31040   var domain = [0, 1];
31041
31042   function scale(x) {
31043     return +x;
31044   }
31045
31046   scale.invert = scale;
31047
31048   scale.domain = scale.range = function(_) {
31049     return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();
31050   };
31051
31052   scale.copy = function() {
31053     return identity$6().domain(domain);
31054   };
31055
31056   return linearish(scale);
31057 }
31058
31059 var nice = function(domain, interval) {
31060   domain = domain.slice();
31061
31062   var i0 = 0,
31063       i1 = domain.length - 1,
31064       x0 = domain[i0],
31065       x1 = domain[i1],
31066       t;
31067
31068   if (x1 < x0) {
31069     t = i0, i0 = i1, i1 = t;
31070     t = x0, x0 = x1, x1 = t;
31071   }
31072
31073   domain[i0] = interval.floor(x0);
31074   domain[i1] = interval.ceil(x1);
31075   return domain;
31076 };
31077
31078 function deinterpolate(a, b) {
31079   return (b = Math.log(b / a))
31080       ? function(x) { return Math.log(x / a) / b; }
31081       : constant$9(b);
31082 }
31083
31084 function reinterpolate$1(a, b) {
31085   return a < 0
31086       ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
31087       : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
31088 }
31089
31090 function pow10(x) {
31091   return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
31092 }
31093
31094 function powp(base) {
31095   return base === 10 ? pow10
31096       : base === Math.E ? Math.exp
31097       : function(x) { return Math.pow(base, x); };
31098 }
31099
31100 function logp(base) {
31101   return base === Math.E ? Math.log
31102       : base === 10 && Math.log10
31103       || base === 2 && Math.log2
31104       || (base = Math.log(base), function(x) { return Math.log(x) / base; });
31105 }
31106
31107 function reflect(f) {
31108   return function(x) {
31109     return -f(-x);
31110   };
31111 }
31112
31113 function log$1() {
31114   var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]),
31115       domain = scale.domain,
31116       base = 10,
31117       logs = logp(10),
31118       pows = powp(10);
31119
31120   function rescale() {
31121     logs = logp(base), pows = powp(base);
31122     if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
31123     return scale;
31124   }
31125
31126   scale.base = function(_) {
31127     return arguments.length ? (base = +_, rescale()) : base;
31128   };
31129
31130   scale.domain = function(_) {
31131     return arguments.length ? (domain(_), rescale()) : domain();
31132   };
31133
31134   scale.ticks = function(count) {
31135     var d = domain(),
31136         u = d[0],
31137         v = d[d.length - 1],
31138         r;
31139
31140     if (r = v < u) i = u, u = v, v = i;
31141
31142     var i = logs(u),
31143         j = logs(v),
31144         p,
31145         k,
31146         t,
31147         n = count == null ? 10 : +count,
31148         z = [];
31149
31150     if (!(base % 1) && j - i < n) {
31151       i = Math.round(i) - 1, j = Math.round(j) + 1;
31152       if (u > 0) for (; i < j; ++i) {
31153         for (k = 1, p = pows(i); k < base; ++k) {
31154           t = p * k;
31155           if (t < u) continue;
31156           if (t > v) break;
31157           z.push(t);
31158         }
31159       } else for (; i < j; ++i) {
31160         for (k = base - 1, p = pows(i); k >= 1; --k) {
31161           t = p * k;
31162           if (t < u) continue;
31163           if (t > v) break;
31164           z.push(t);
31165         }
31166       }
31167     } else {
31168       z = ticks(i, j, Math.min(j - i, n)).map(pows);
31169     }
31170
31171     return r ? z.reverse() : z;
31172   };
31173
31174   scale.tickFormat = function(count, specifier) {
31175     if (specifier == null) specifier = base === 10 ? ".0e" : ",";
31176     if (typeof specifier !== "function") specifier = format(specifier);
31177     if (count === Infinity) return specifier;
31178     if (count == null) count = 10;
31179     var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
31180     return function(d) {
31181       var i = d / pows(Math.round(logs(d)));
31182       if (i * base < base - 0.5) i *= base;
31183       return i <= k ? specifier(d) : "";
31184     };
31185   };
31186
31187   scale.nice = function() {
31188     return domain(nice(domain(), {
31189       floor: function(x) { return pows(Math.floor(logs(x))); },
31190       ceil: function(x) { return pows(Math.ceil(logs(x))); }
31191     }));
31192   };
31193
31194   scale.copy = function() {
31195     return copy(scale, log$1().base(base));
31196   };
31197
31198   return scale;
31199 }
31200
31201 function raise$1(x, exponent) {
31202   return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
31203 }
31204
31205 function pow$1() {
31206   var exponent = 1,
31207       scale = continuous(deinterpolate, reinterpolate),
31208       domain = scale.domain;
31209
31210   function deinterpolate(a, b) {
31211     return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))
31212         ? function(x) { return (raise$1(x, exponent) - a) / b; }
31213         : constant$9(b);
31214   }
31215
31216   function reinterpolate(a, b) {
31217     b = raise$1(b, exponent) - (a = raise$1(a, exponent));
31218     return function(t) { return raise$1(a + b * t, 1 / exponent); };
31219   }
31220
31221   scale.exponent = function(_) {
31222     return arguments.length ? (exponent = +_, domain(domain())) : exponent;
31223   };
31224
31225   scale.copy = function() {
31226     return copy(scale, pow$1().exponent(exponent));
31227   };
31228
31229   return linearish(scale);
31230 }
31231
31232 function sqrt$1() {
31233   return pow$1().exponent(0.5);
31234 }
31235
31236 function quantile() {
31237   var domain = [],
31238       range = [],
31239       thresholds = [];
31240
31241   function rescale() {
31242     var i = 0, n = Math.max(1, range.length);
31243     thresholds = new Array(n - 1);
31244     while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
31245     return scale;
31246   }
31247
31248   function scale(x) {
31249     if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)];
31250   }
31251
31252   scale.invertExtent = function(y) {
31253     var i = range.indexOf(y);
31254     return i < 0 ? [NaN, NaN] : [
31255       i > 0 ? thresholds[i - 1] : domain[0],
31256       i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
31257     ];
31258   };
31259
31260   scale.domain = function(_) {
31261     if (!arguments.length) return domain.slice();
31262     domain = [];
31263     for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
31264     domain.sort(ascending);
31265     return rescale();
31266   };
31267
31268   scale.range = function(_) {
31269     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
31270   };
31271
31272   scale.quantiles = function() {
31273     return thresholds.slice();
31274   };
31275
31276   scale.copy = function() {
31277     return quantile()
31278         .domain(domain)
31279         .range(range);
31280   };
31281
31282   return scale;
31283 }
31284
31285 function quantize$1() {
31286   var x0 = 0,
31287       x1 = 1,
31288       n = 1,
31289       domain = [0.5],
31290       range = [0, 1];
31291
31292   function scale(x) {
31293     if (x <= x) return range[bisectRight(domain, x, 0, n)];
31294   }
31295
31296   function rescale() {
31297     var i = -1;
31298     domain = new Array(n);
31299     while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
31300     return scale;
31301   }
31302
31303   scale.domain = function(_) {
31304     return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
31305   };
31306
31307   scale.range = function(_) {
31308     return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice();
31309   };
31310
31311   scale.invertExtent = function(y) {
31312     var i = range.indexOf(y);
31313     return i < 0 ? [NaN, NaN]
31314         : i < 1 ? [x0, domain[0]]
31315         : i >= n ? [domain[n - 1], x1]
31316         : [domain[i - 1], domain[i]];
31317   };
31318
31319   scale.copy = function() {
31320     return quantize$1()
31321         .domain([x0, x1])
31322         .range(range);
31323   };
31324
31325   return linearish(scale);
31326 }
31327
31328 function threshold$1() {
31329   var domain = [0.5],
31330       range = [0, 1],
31331       n = 1;
31332
31333   function scale(x) {
31334     if (x <= x) return range[bisectRight(domain, x, 0, n)];
31335   }
31336
31337   scale.domain = function(_) {
31338     return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
31339   };
31340
31341   scale.range = function(_) {
31342     return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();
31343   };
31344
31345   scale.invertExtent = function(y) {
31346     var i = range.indexOf(y);
31347     return [domain[i - 1], domain[i]];
31348   };
31349
31350   scale.copy = function() {
31351     return threshold$1()
31352         .domain(domain)
31353         .range(range);
31354   };
31355
31356   return scale;
31357 }
31358
31359 var t0$1 = new Date;
31360 var t1$1 = new Date;
31361
31362 function newInterval(floori, offseti, count, field) {
31363
31364   function interval(date) {
31365     return floori(date = new Date(+date)), date;
31366   }
31367
31368   interval.floor = interval;
31369
31370   interval.ceil = function(date) {
31371     return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
31372   };
31373
31374   interval.round = function(date) {
31375     var d0 = interval(date),
31376         d1 = interval.ceil(date);
31377     return date - d0 < d1 - date ? d0 : d1;
31378   };
31379
31380   interval.offset = function(date, step) {
31381     return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
31382   };
31383
31384   interval.range = function(start, stop, step) {
31385     var range = [];
31386     start = interval.ceil(start);
31387     step = step == null ? 1 : Math.floor(step);
31388     if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
31389     do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)
31390     return range;
31391   };
31392
31393   interval.filter = function(test) {
31394     return newInterval(function(date) {
31395       if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
31396     }, function(date, step) {
31397       if (date >= date) {
31398         if (step < 0) while (++step <= 0) {
31399           while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
31400         } else while (--step >= 0) {
31401           while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
31402         }
31403       }
31404     });
31405   };
31406
31407   if (count) {
31408     interval.count = function(start, end) {
31409       t0$1.setTime(+start), t1$1.setTime(+end);
31410       floori(t0$1), floori(t1$1);
31411       return Math.floor(count(t0$1, t1$1));
31412     };
31413
31414     interval.every = function(step) {
31415       step = Math.floor(step);
31416       return !isFinite(step) || !(step > 0) ? null
31417           : !(step > 1) ? interval
31418           : interval.filter(field
31419               ? function(d) { return field(d) % step === 0; }
31420               : function(d) { return interval.count(0, d) % step === 0; });
31421     };
31422   }
31423
31424   return interval;
31425 }
31426
31427 var millisecond = newInterval(function() {
31428   // noop
31429 }, function(date, step) {
31430   date.setTime(+date + step);
31431 }, function(start, end) {
31432   return end - start;
31433 });
31434
31435 // An optimized implementation for this simple case.
31436 millisecond.every = function(k) {
31437   k = Math.floor(k);
31438   if (!isFinite(k) || !(k > 0)) return null;
31439   if (!(k > 1)) return millisecond;
31440   return newInterval(function(date) {
31441     date.setTime(Math.floor(date / k) * k);
31442   }, function(date, step) {
31443     date.setTime(+date + step * k);
31444   }, function(start, end) {
31445     return (end - start) / k;
31446   });
31447 };
31448
31449 var milliseconds = millisecond.range;
31450
31451 var durationSecond$1 = 1e3;
31452 var durationMinute$1 = 6e4;
31453 var durationHour$1 = 36e5;
31454 var durationDay$1 = 864e5;
31455 var durationWeek$1 = 6048e5;
31456
31457 var second = newInterval(function(date) {
31458   date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);
31459 }, function(date, step) {
31460   date.setTime(+date + step * durationSecond$1);
31461 }, function(start, end) {
31462   return (end - start) / durationSecond$1;
31463 }, function(date) {
31464   return date.getUTCSeconds();
31465 });
31466
31467 var seconds = second.range;
31468
31469 var minute = newInterval(function(date) {
31470   date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);
31471 }, function(date, step) {
31472   date.setTime(+date + step * durationMinute$1);
31473 }, function(start, end) {
31474   return (end - start) / durationMinute$1;
31475 }, function(date) {
31476   return date.getMinutes();
31477 });
31478
31479 var minutes = minute.range;
31480
31481 var hour = newInterval(function(date) {
31482   var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;
31483   if (offset < 0) offset += durationHour$1;
31484   date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);
31485 }, function(date, step) {
31486   date.setTime(+date + step * durationHour$1);
31487 }, function(start, end) {
31488   return (end - start) / durationHour$1;
31489 }, function(date) {
31490   return date.getHours();
31491 });
31492
31493 var hours = hour.range;
31494
31495 var day = newInterval(function(date) {
31496   date.setHours(0, 0, 0, 0);
31497 }, function(date, step) {
31498   date.setDate(date.getDate() + step);
31499 }, function(start, end) {
31500   return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;
31501 }, function(date) {
31502   return date.getDate() - 1;
31503 });
31504
31505 var days = day.range;
31506
31507 function weekday(i) {
31508   return newInterval(function(date) {
31509     date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
31510     date.setHours(0, 0, 0, 0);
31511   }, function(date, step) {
31512     date.setDate(date.getDate() + step * 7);
31513   }, function(start, end) {
31514     return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;
31515   });
31516 }
31517
31518 var sunday = weekday(0);
31519 var monday = weekday(1);
31520 var tuesday = weekday(2);
31521 var wednesday = weekday(3);
31522 var thursday = weekday(4);
31523 var friday = weekday(5);
31524 var saturday = weekday(6);
31525
31526 var sundays = sunday.range;
31527 var mondays = monday.range;
31528 var tuesdays = tuesday.range;
31529 var wednesdays = wednesday.range;
31530 var thursdays = thursday.range;
31531 var fridays = friday.range;
31532 var saturdays = saturday.range;
31533
31534 var month = newInterval(function(date) {
31535   date.setDate(1);
31536   date.setHours(0, 0, 0, 0);
31537 }, function(date, step) {
31538   date.setMonth(date.getMonth() + step);
31539 }, function(start, end) {
31540   return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
31541 }, function(date) {
31542   return date.getMonth();
31543 });
31544
31545 var months = month.range;
31546
31547 var year = newInterval(function(date) {
31548   date.setMonth(0, 1);
31549   date.setHours(0, 0, 0, 0);
31550 }, function(date, step) {
31551   date.setFullYear(date.getFullYear() + step);
31552 }, function(start, end) {
31553   return end.getFullYear() - start.getFullYear();
31554 }, function(date) {
31555   return date.getFullYear();
31556 });
31557
31558 // An optimized implementation for this simple case.
31559 year.every = function(k) {
31560   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
31561     date.setFullYear(Math.floor(date.getFullYear() / k) * k);
31562     date.setMonth(0, 1);
31563     date.setHours(0, 0, 0, 0);
31564   }, function(date, step) {
31565     date.setFullYear(date.getFullYear() + step * k);
31566   });
31567 };
31568
31569 var years = year.range;
31570
31571 var utcMinute = newInterval(function(date) {
31572   date.setUTCSeconds(0, 0);
31573 }, function(date, step) {
31574   date.setTime(+date + step * durationMinute$1);
31575 }, function(start, end) {
31576   return (end - start) / durationMinute$1;
31577 }, function(date) {
31578   return date.getUTCMinutes();
31579 });
31580
31581 var utcMinutes = utcMinute.range;
31582
31583 var utcHour = newInterval(function(date) {
31584   date.setUTCMinutes(0, 0, 0);
31585 }, function(date, step) {
31586   date.setTime(+date + step * durationHour$1);
31587 }, function(start, end) {
31588   return (end - start) / durationHour$1;
31589 }, function(date) {
31590   return date.getUTCHours();
31591 });
31592
31593 var utcHours = utcHour.range;
31594
31595 var utcDay = newInterval(function(date) {
31596   date.setUTCHours(0, 0, 0, 0);
31597 }, function(date, step) {
31598   date.setUTCDate(date.getUTCDate() + step);
31599 }, function(start, end) {
31600   return (end - start) / durationDay$1;
31601 }, function(date) {
31602   return date.getUTCDate() - 1;
31603 });
31604
31605 var utcDays = utcDay.range;
31606
31607 function utcWeekday(i) {
31608   return newInterval(function(date) {
31609     date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
31610     date.setUTCHours(0, 0, 0, 0);
31611   }, function(date, step) {
31612     date.setUTCDate(date.getUTCDate() + step * 7);
31613   }, function(start, end) {
31614     return (end - start) / durationWeek$1;
31615   });
31616 }
31617
31618 var utcSunday = utcWeekday(0);
31619 var utcMonday = utcWeekday(1);
31620 var utcTuesday = utcWeekday(2);
31621 var utcWednesday = utcWeekday(3);
31622 var utcThursday = utcWeekday(4);
31623 var utcFriday = utcWeekday(5);
31624 var utcSaturday = utcWeekday(6);
31625
31626 var utcSundays = utcSunday.range;
31627 var utcMondays = utcMonday.range;
31628 var utcTuesdays = utcTuesday.range;
31629 var utcWednesdays = utcWednesday.range;
31630 var utcThursdays = utcThursday.range;
31631 var utcFridays = utcFriday.range;
31632 var utcSaturdays = utcSaturday.range;
31633
31634 var utcMonth = newInterval(function(date) {
31635   date.setUTCDate(1);
31636   date.setUTCHours(0, 0, 0, 0);
31637 }, function(date, step) {
31638   date.setUTCMonth(date.getUTCMonth() + step);
31639 }, function(start, end) {
31640   return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
31641 }, function(date) {
31642   return date.getUTCMonth();
31643 });
31644
31645 var utcMonths = utcMonth.range;
31646
31647 var utcYear = newInterval(function(date) {
31648   date.setUTCMonth(0, 1);
31649   date.setUTCHours(0, 0, 0, 0);
31650 }, function(date, step) {
31651   date.setUTCFullYear(date.getUTCFullYear() + step);
31652 }, function(start, end) {
31653   return end.getUTCFullYear() - start.getUTCFullYear();
31654 }, function(date) {
31655   return date.getUTCFullYear();
31656 });
31657
31658 // An optimized implementation for this simple case.
31659 utcYear.every = function(k) {
31660   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
31661     date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
31662     date.setUTCMonth(0, 1);
31663     date.setUTCHours(0, 0, 0, 0);
31664   }, function(date, step) {
31665     date.setUTCFullYear(date.getUTCFullYear() + step * k);
31666   });
31667 };
31668
31669 var utcYears = utcYear.range;
31670
31671 function localDate(d) {
31672   if (0 <= d.y && d.y < 100) {
31673     var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
31674     date.setFullYear(d.y);
31675     return date;
31676   }
31677   return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
31678 }
31679
31680 function utcDate(d) {
31681   if (0 <= d.y && d.y < 100) {
31682     var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
31683     date.setUTCFullYear(d.y);
31684     return date;
31685   }
31686   return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
31687 }
31688
31689 function newYear(y) {
31690   return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
31691 }
31692
31693 function formatLocale$1(locale) {
31694   var locale_dateTime = locale.dateTime,
31695       locale_date = locale.date,
31696       locale_time = locale.time,
31697       locale_periods = locale.periods,
31698       locale_weekdays = locale.days,
31699       locale_shortWeekdays = locale.shortDays,
31700       locale_months = locale.months,
31701       locale_shortMonths = locale.shortMonths;
31702
31703   var periodRe = formatRe(locale_periods),
31704       periodLookup = formatLookup(locale_periods),
31705       weekdayRe = formatRe(locale_weekdays),
31706       weekdayLookup = formatLookup(locale_weekdays),
31707       shortWeekdayRe = formatRe(locale_shortWeekdays),
31708       shortWeekdayLookup = formatLookup(locale_shortWeekdays),
31709       monthRe = formatRe(locale_months),
31710       monthLookup = formatLookup(locale_months),
31711       shortMonthRe = formatRe(locale_shortMonths),
31712       shortMonthLookup = formatLookup(locale_shortMonths);
31713
31714   var formats = {
31715     "a": formatShortWeekday,
31716     "A": formatWeekday,
31717     "b": formatShortMonth,
31718     "B": formatMonth,
31719     "c": null,
31720     "d": formatDayOfMonth,
31721     "e": formatDayOfMonth,
31722     "H": formatHour24,
31723     "I": formatHour12,
31724     "j": formatDayOfYear,
31725     "L": formatMilliseconds,
31726     "m": formatMonthNumber,
31727     "M": formatMinutes,
31728     "p": formatPeriod,
31729     "S": formatSeconds,
31730     "U": formatWeekNumberSunday,
31731     "w": formatWeekdayNumber,
31732     "W": formatWeekNumberMonday,
31733     "x": null,
31734     "X": null,
31735     "y": formatYear,
31736     "Y": formatFullYear,
31737     "Z": formatZone,
31738     "%": formatLiteralPercent
31739   };
31740
31741   var utcFormats = {
31742     "a": formatUTCShortWeekday,
31743     "A": formatUTCWeekday,
31744     "b": formatUTCShortMonth,
31745     "B": formatUTCMonth,
31746     "c": null,
31747     "d": formatUTCDayOfMonth,
31748     "e": formatUTCDayOfMonth,
31749     "H": formatUTCHour24,
31750     "I": formatUTCHour12,
31751     "j": formatUTCDayOfYear,
31752     "L": formatUTCMilliseconds,
31753     "m": formatUTCMonthNumber,
31754     "M": formatUTCMinutes,
31755     "p": formatUTCPeriod,
31756     "S": formatUTCSeconds,
31757     "U": formatUTCWeekNumberSunday,
31758     "w": formatUTCWeekdayNumber,
31759     "W": formatUTCWeekNumberMonday,
31760     "x": null,
31761     "X": null,
31762     "y": formatUTCYear,
31763     "Y": formatUTCFullYear,
31764     "Z": formatUTCZone,
31765     "%": formatLiteralPercent
31766   };
31767
31768   var parses = {
31769     "a": parseShortWeekday,
31770     "A": parseWeekday,
31771     "b": parseShortMonth,
31772     "B": parseMonth,
31773     "c": parseLocaleDateTime,
31774     "d": parseDayOfMonth,
31775     "e": parseDayOfMonth,
31776     "H": parseHour24,
31777     "I": parseHour24,
31778     "j": parseDayOfYear,
31779     "L": parseMilliseconds,
31780     "m": parseMonthNumber,
31781     "M": parseMinutes,
31782     "p": parsePeriod,
31783     "S": parseSeconds,
31784     "U": parseWeekNumberSunday,
31785     "w": parseWeekdayNumber,
31786     "W": parseWeekNumberMonday,
31787     "x": parseLocaleDate,
31788     "X": parseLocaleTime,
31789     "y": parseYear,
31790     "Y": parseFullYear,
31791     "Z": parseZone,
31792     "%": parseLiteralPercent
31793   };
31794
31795   // These recursive directive definitions must be deferred.
31796   formats.x = newFormat(locale_date, formats);
31797   formats.X = newFormat(locale_time, formats);
31798   formats.c = newFormat(locale_dateTime, formats);
31799   utcFormats.x = newFormat(locale_date, utcFormats);
31800   utcFormats.X = newFormat(locale_time, utcFormats);
31801   utcFormats.c = newFormat(locale_dateTime, utcFormats);
31802
31803   function newFormat(specifier, formats) {
31804     return function(date) {
31805       var string = [],
31806           i = -1,
31807           j = 0,
31808           n = specifier.length,
31809           c,
31810           pad,
31811           format;
31812
31813       if (!(date instanceof Date)) date = new Date(+date);
31814
31815       while (++i < n) {
31816         if (specifier.charCodeAt(i) === 37) {
31817           string.push(specifier.slice(j, i));
31818           if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
31819           else pad = c === "e" ? " " : "0";
31820           if (format = formats[c]) c = format(date, pad);
31821           string.push(c);
31822           j = i + 1;
31823         }
31824       }
31825
31826       string.push(specifier.slice(j, i));
31827       return string.join("");
31828     };
31829   }
31830
31831   function newParse(specifier, newDate) {
31832     return function(string) {
31833       var d = newYear(1900),
31834           i = parseSpecifier(d, specifier, string += "", 0);
31835       if (i != string.length) return null;
31836
31837       // The am-pm flag is 0 for AM, and 1 for PM.
31838       if ("p" in d) d.H = d.H % 12 + d.p * 12;
31839
31840       // Convert day-of-week and week-of-year to day-of-year.
31841       if ("W" in d || "U" in d) {
31842         if (!("w" in d)) d.w = "W" in d ? 1 : 0;
31843         var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
31844         d.m = 0;
31845         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;
31846       }
31847
31848       // If a time zone is specified, all fields are interpreted as UTC and then
31849       // offset according to the specified time zone.
31850       if ("Z" in d) {
31851         d.H += d.Z / 100 | 0;
31852         d.M += d.Z % 100;
31853         return utcDate(d);
31854       }
31855
31856       // Otherwise, all fields are in local time.
31857       return newDate(d);
31858     };
31859   }
31860
31861   function parseSpecifier(d, specifier, string, j) {
31862     var i = 0,
31863         n = specifier.length,
31864         m = string.length,
31865         c,
31866         parse;
31867
31868     while (i < n) {
31869       if (j >= m) return -1;
31870       c = specifier.charCodeAt(i++);
31871       if (c === 37) {
31872         c = specifier.charAt(i++);
31873         parse = parses[c in pads ? specifier.charAt(i++) : c];
31874         if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
31875       } else if (c != string.charCodeAt(j++)) {
31876         return -1;
31877       }
31878     }
31879
31880     return j;
31881   }
31882
31883   function parsePeriod(d, string, i) {
31884     var n = periodRe.exec(string.slice(i));
31885     return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31886   }
31887
31888   function parseShortWeekday(d, string, i) {
31889     var n = shortWeekdayRe.exec(string.slice(i));
31890     return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31891   }
31892
31893   function parseWeekday(d, string, i) {
31894     var n = weekdayRe.exec(string.slice(i));
31895     return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31896   }
31897
31898   function parseShortMonth(d, string, i) {
31899     var n = shortMonthRe.exec(string.slice(i));
31900     return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31901   }
31902
31903   function parseMonth(d, string, i) {
31904     var n = monthRe.exec(string.slice(i));
31905     return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31906   }
31907
31908   function parseLocaleDateTime(d, string, i) {
31909     return parseSpecifier(d, locale_dateTime, string, i);
31910   }
31911
31912   function parseLocaleDate(d, string, i) {
31913     return parseSpecifier(d, locale_date, string, i);
31914   }
31915
31916   function parseLocaleTime(d, string, i) {
31917     return parseSpecifier(d, locale_time, string, i);
31918   }
31919
31920   function formatShortWeekday(d) {
31921     return locale_shortWeekdays[d.getDay()];
31922   }
31923
31924   function formatWeekday(d) {
31925     return locale_weekdays[d.getDay()];
31926   }
31927
31928   function formatShortMonth(d) {
31929     return locale_shortMonths[d.getMonth()];
31930   }
31931
31932   function formatMonth(d) {
31933     return locale_months[d.getMonth()];
31934   }
31935
31936   function formatPeriod(d) {
31937     return locale_periods[+(d.getHours() >= 12)];
31938   }
31939
31940   function formatUTCShortWeekday(d) {
31941     return locale_shortWeekdays[d.getUTCDay()];
31942   }
31943
31944   function formatUTCWeekday(d) {
31945     return locale_weekdays[d.getUTCDay()];
31946   }
31947
31948   function formatUTCShortMonth(d) {
31949     return locale_shortMonths[d.getUTCMonth()];
31950   }
31951
31952   function formatUTCMonth(d) {
31953     return locale_months[d.getUTCMonth()];
31954   }
31955
31956   function formatUTCPeriod(d) {
31957     return locale_periods[+(d.getUTCHours() >= 12)];
31958   }
31959
31960   return {
31961     format: function(specifier) {
31962       var f = newFormat(specifier += "", formats);
31963       f.toString = function() { return specifier; };
31964       return f;
31965     },
31966     parse: function(specifier) {
31967       var p = newParse(specifier += "", localDate);
31968       p.toString = function() { return specifier; };
31969       return p;
31970     },
31971     utcFormat: function(specifier) {
31972       var f = newFormat(specifier += "", utcFormats);
31973       f.toString = function() { return specifier; };
31974       return f;
31975     },
31976     utcParse: function(specifier) {
31977       var p = newParse(specifier, utcDate);
31978       p.toString = function() { return specifier; };
31979       return p;
31980     }
31981   };
31982 }
31983
31984 var pads = {"-": "", "_": " ", "0": "0"};
31985 var numberRe = /^\s*\d+/;
31986 var percentRe = /^%/;
31987 var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
31988
31989 function pad(value, fill, width) {
31990   var sign = value < 0 ? "-" : "",
31991       string = (sign ? -value : value) + "",
31992       length = string.length;
31993   return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
31994 }
31995
31996 function requote(s) {
31997   return s.replace(requoteRe, "\\$&");
31998 }
31999
32000 function formatRe(names) {
32001   return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
32002 }
32003
32004 function formatLookup(names) {
32005   var map = {}, i = -1, n = names.length;
32006   while (++i < n) map[names[i].toLowerCase()] = i;
32007   return map;
32008 }
32009
32010 function parseWeekdayNumber(d, string, i) {
32011   var n = numberRe.exec(string.slice(i, i + 1));
32012   return n ? (d.w = +n[0], i + n[0].length) : -1;
32013 }
32014
32015 function parseWeekNumberSunday(d, string, i) {
32016   var n = numberRe.exec(string.slice(i));
32017   return n ? (d.U = +n[0], i + n[0].length) : -1;
32018 }
32019
32020 function parseWeekNumberMonday(d, string, i) {
32021   var n = numberRe.exec(string.slice(i));
32022   return n ? (d.W = +n[0], i + n[0].length) : -1;
32023 }
32024
32025 function parseFullYear(d, string, i) {
32026   var n = numberRe.exec(string.slice(i, i + 4));
32027   return n ? (d.y = +n[0], i + n[0].length) : -1;
32028 }
32029
32030 function parseYear(d, string, i) {
32031   var n = numberRe.exec(string.slice(i, i + 2));
32032   return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
32033 }
32034
32035 function parseZone(d, string, i) {
32036   var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
32037   return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
32038 }
32039
32040 function parseMonthNumber(d, string, i) {
32041   var n = numberRe.exec(string.slice(i, i + 2));
32042   return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
32043 }
32044
32045 function parseDayOfMonth(d, string, i) {
32046   var n = numberRe.exec(string.slice(i, i + 2));
32047   return n ? (d.d = +n[0], i + n[0].length) : -1;
32048 }
32049
32050 function parseDayOfYear(d, string, i) {
32051   var n = numberRe.exec(string.slice(i, i + 3));
32052   return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
32053 }
32054
32055 function parseHour24(d, string, i) {
32056   var n = numberRe.exec(string.slice(i, i + 2));
32057   return n ? (d.H = +n[0], i + n[0].length) : -1;
32058 }
32059
32060 function parseMinutes(d, string, i) {
32061   var n = numberRe.exec(string.slice(i, i + 2));
32062   return n ? (d.M = +n[0], i + n[0].length) : -1;
32063 }
32064
32065 function parseSeconds(d, string, i) {
32066   var n = numberRe.exec(string.slice(i, i + 2));
32067   return n ? (d.S = +n[0], i + n[0].length) : -1;
32068 }
32069
32070 function parseMilliseconds(d, string, i) {
32071   var n = numberRe.exec(string.slice(i, i + 3));
32072   return n ? (d.L = +n[0], i + n[0].length) : -1;
32073 }
32074
32075 function parseLiteralPercent(d, string, i) {
32076   var n = percentRe.exec(string.slice(i, i + 1));
32077   return n ? i + n[0].length : -1;
32078 }
32079
32080 function formatDayOfMonth(d, p) {
32081   return pad(d.getDate(), p, 2);
32082 }
32083
32084 function formatHour24(d, p) {
32085   return pad(d.getHours(), p, 2);
32086 }
32087
32088 function formatHour12(d, p) {
32089   return pad(d.getHours() % 12 || 12, p, 2);
32090 }
32091
32092 function formatDayOfYear(d, p) {
32093   return pad(1 + day.count(year(d), d), p, 3);
32094 }
32095
32096 function formatMilliseconds(d, p) {
32097   return pad(d.getMilliseconds(), p, 3);
32098 }
32099
32100 function formatMonthNumber(d, p) {
32101   return pad(d.getMonth() + 1, p, 2);
32102 }
32103
32104 function formatMinutes(d, p) {
32105   return pad(d.getMinutes(), p, 2);
32106 }
32107
32108 function formatSeconds(d, p) {
32109   return pad(d.getSeconds(), p, 2);
32110 }
32111
32112 function formatWeekNumberSunday(d, p) {
32113   return pad(sunday.count(year(d), d), p, 2);
32114 }
32115
32116 function formatWeekdayNumber(d) {
32117   return d.getDay();
32118 }
32119
32120 function formatWeekNumberMonday(d, p) {
32121   return pad(monday.count(year(d), d), p, 2);
32122 }
32123
32124 function formatYear(d, p) {
32125   return pad(d.getFullYear() % 100, p, 2);
32126 }
32127
32128 function formatFullYear(d, p) {
32129   return pad(d.getFullYear() % 10000, p, 4);
32130 }
32131
32132 function formatZone(d) {
32133   var z = d.getTimezoneOffset();
32134   return (z > 0 ? "-" : (z *= -1, "+"))
32135       + pad(z / 60 | 0, "0", 2)
32136       + pad(z % 60, "0", 2);
32137 }
32138
32139 function formatUTCDayOfMonth(d, p) {
32140   return pad(d.getUTCDate(), p, 2);
32141 }
32142
32143 function formatUTCHour24(d, p) {
32144   return pad(d.getUTCHours(), p, 2);
32145 }
32146
32147 function formatUTCHour12(d, p) {
32148   return pad(d.getUTCHours() % 12 || 12, p, 2);
32149 }
32150
32151 function formatUTCDayOfYear(d, p) {
32152   return pad(1 + utcDay.count(utcYear(d), d), p, 3);
32153 }
32154
32155 function formatUTCMilliseconds(d, p) {
32156   return pad(d.getUTCMilliseconds(), p, 3);
32157 }
32158
32159 function formatUTCMonthNumber(d, p) {
32160   return pad(d.getUTCMonth() + 1, p, 2);
32161 }
32162
32163 function formatUTCMinutes(d, p) {
32164   return pad(d.getUTCMinutes(), p, 2);
32165 }
32166
32167 function formatUTCSeconds(d, p) {
32168   return pad(d.getUTCSeconds(), p, 2);
32169 }
32170
32171 function formatUTCWeekNumberSunday(d, p) {
32172   return pad(utcSunday.count(utcYear(d), d), p, 2);
32173 }
32174
32175 function formatUTCWeekdayNumber(d) {
32176   return d.getUTCDay();
32177 }
32178
32179 function formatUTCWeekNumberMonday(d, p) {
32180   return pad(utcMonday.count(utcYear(d), d), p, 2);
32181 }
32182
32183 function formatUTCYear(d, p) {
32184   return pad(d.getUTCFullYear() % 100, p, 2);
32185 }
32186
32187 function formatUTCFullYear(d, p) {
32188   return pad(d.getUTCFullYear() % 10000, p, 4);
32189 }
32190
32191 function formatUTCZone() {
32192   return "+0000";
32193 }
32194
32195 function formatLiteralPercent() {
32196   return "%";
32197 }
32198
32199 var locale$2;
32200 var timeFormat;
32201 var timeParse;
32202 var utcFormat;
32203 var utcParse;
32204
32205 defaultLocale$1({
32206   dateTime: "%x, %X",
32207   date: "%-m/%-d/%Y",
32208   time: "%-I:%M:%S %p",
32209   periods: ["AM", "PM"],
32210   days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
32211   shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
32212   months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
32213   shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
32214 });
32215
32216 function defaultLocale$1(definition) {
32217   locale$2 = formatLocale$1(definition);
32218   timeFormat = locale$2.format;
32219   timeParse = locale$2.parse;
32220   utcFormat = locale$2.utcFormat;
32221   utcParse = locale$2.utcParse;
32222   return locale$2;
32223 }
32224
32225 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
32226
32227 function formatIsoNative(date) {
32228   return date.toISOString();
32229 }
32230
32231 var formatIso = Date.prototype.toISOString
32232     ? formatIsoNative
32233     : utcFormat(isoSpecifier);
32234
32235 function parseIsoNative(string) {
32236   var date = new Date(string);
32237   return isNaN(date) ? null : date;
32238 }
32239
32240 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
32241     ? parseIsoNative
32242     : utcParse(isoSpecifier);
32243
32244 var durationSecond = 1000;
32245 var durationMinute = durationSecond * 60;
32246 var durationHour = durationMinute * 60;
32247 var durationDay = durationHour * 24;
32248 var durationWeek = durationDay * 7;
32249 var durationMonth = durationDay * 30;
32250 var durationYear = durationDay * 365;
32251
32252 function date$1(t) {
32253   return new Date(t);
32254 }
32255
32256 function number$3(t) {
32257   return t instanceof Date ? +t : +new Date(+t);
32258 }
32259
32260 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
32261   var scale = continuous(deinterpolateLinear, reinterpolate),
32262       invert = scale.invert,
32263       domain = scale.domain;
32264
32265   var formatMillisecond = format(".%L"),
32266       formatSecond = format(":%S"),
32267       formatMinute = format("%I:%M"),
32268       formatHour = format("%I %p"),
32269       formatDay = format("%a %d"),
32270       formatWeek = format("%b %d"),
32271       formatMonth = format("%B"),
32272       formatYear = format("%Y");
32273
32274   var tickIntervals = [
32275     [second$$1,  1,      durationSecond],
32276     [second$$1,  5,  5 * durationSecond],
32277     [second$$1, 15, 15 * durationSecond],
32278     [second$$1, 30, 30 * durationSecond],
32279     [minute$$1,  1,      durationMinute],
32280     [minute$$1,  5,  5 * durationMinute],
32281     [minute$$1, 15, 15 * durationMinute],
32282     [minute$$1, 30, 30 * durationMinute],
32283     [  hour$$1,  1,      durationHour  ],
32284     [  hour$$1,  3,  3 * durationHour  ],
32285     [  hour$$1,  6,  6 * durationHour  ],
32286     [  hour$$1, 12, 12 * durationHour  ],
32287     [   day$$1,  1,      durationDay   ],
32288     [   day$$1,  2,  2 * durationDay   ],
32289     [  week,  1,      durationWeek  ],
32290     [ month$$1,  1,      durationMonth ],
32291     [ month$$1,  3,  3 * durationMonth ],
32292     [  year$$1,  1,      durationYear  ]
32293   ];
32294
32295   function tickFormat(date$$1) {
32296     return (second$$1(date$$1) < date$$1 ? formatMillisecond
32297         : minute$$1(date$$1) < date$$1 ? formatSecond
32298         : hour$$1(date$$1) < date$$1 ? formatMinute
32299         : day$$1(date$$1) < date$$1 ? formatHour
32300         : month$$1(date$$1) < date$$1 ? (week(date$$1) < date$$1 ? formatDay : formatWeek)
32301         : year$$1(date$$1) < date$$1 ? formatMonth
32302         : formatYear)(date$$1);
32303   }
32304
32305   function tickInterval(interval$$1, start, stop, step) {
32306     if (interval$$1 == null) interval$$1 = 10;
32307
32308     // If a desired tick count is specified, pick a reasonable tick interval
32309     // based on the extent of the domain and a rough estimate of tick size.
32310     // Otherwise, assume interval is already a time interval and use it.
32311     if (typeof interval$$1 === "number") {
32312       var target = Math.abs(stop - start) / interval$$1,
32313           i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);
32314       if (i === tickIntervals.length) {
32315         step = tickStep(start / durationYear, stop / durationYear, interval$$1);
32316         interval$$1 = year$$1;
32317       } else if (i) {
32318         i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
32319         step = i[1];
32320         interval$$1 = i[0];
32321       } else {
32322         step = tickStep(start, stop, interval$$1);
32323         interval$$1 = millisecond$$1;
32324       }
32325     }
32326
32327     return step == null ? interval$$1 : interval$$1.every(step);
32328   }
32329
32330   scale.invert = function(y) {
32331     return new Date(invert(y));
32332   };
32333
32334   scale.domain = function(_) {
32335     return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);
32336   };
32337
32338   scale.ticks = function(interval$$1, step) {
32339     var d = domain(),
32340         t0 = d[0],
32341         t1 = d[d.length - 1],
32342         r = t1 < t0,
32343         t;
32344     if (r) t = t0, t0 = t1, t1 = t;
32345     t = tickInterval(interval$$1, t0, t1, step);
32346     t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
32347     return r ? t.reverse() : t;
32348   };
32349
32350   scale.tickFormat = function(count, specifier) {
32351     return specifier == null ? tickFormat : format(specifier);
32352   };
32353
32354   scale.nice = function(interval$$1, step) {
32355     var d = domain();
32356     return (interval$$1 = tickInterval(interval$$1, d[0], d[d.length - 1], step))
32357         ? domain(nice(d, interval$$1))
32358         : scale;
32359   };
32360
32361   scale.copy = function() {
32362     return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
32363   };
32364
32365   return scale;
32366 }
32367
32368 var time = function() {
32369   return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
32370 };
32371
32372 var utcTime = function() {
32373   return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
32374 };
32375
32376 var colors = function(s) {
32377   return s.match(/.{6}/g).map(function(x) {
32378     return "#" + x;
32379   });
32380 };
32381
32382 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
32383
32384 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
32385
32386 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
32387
32388 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
32389
32390 var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
32391
32392 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
32393
32394 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
32395
32396 var rainbow = cubehelix();
32397
32398 var rainbow$1 = function(t) {
32399   if (t < 0 || t > 1) t -= Math.floor(t);
32400   var ts = Math.abs(t - 0.5);
32401   rainbow.h = 360 * t - 100;
32402   rainbow.s = 1.5 - 1.5 * ts;
32403   rainbow.l = 0.8 - 0.9 * ts;
32404   return rainbow + "";
32405 };
32406
32407 function ramp(range) {
32408   var n = range.length;
32409   return function(t) {
32410     return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
32411   };
32412 }
32413
32414 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
32415
32416 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
32417
32418 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
32419
32420 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
32421
32422 function sequential(interpolator) {
32423   var x0 = 0,
32424       x1 = 1,
32425       clamp = false;
32426
32427   function scale(x) {
32428     var t = (x - x0) / (x1 - x0);
32429     return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
32430   }
32431
32432   scale.domain = function(_) {
32433     return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
32434   };
32435
32436   scale.clamp = function(_) {
32437     return arguments.length ? (clamp = !!_, scale) : clamp;
32438   };
32439
32440   scale.interpolator = function(_) {
32441     return arguments.length ? (interpolator = _, scale) : interpolator;
32442   };
32443
32444   scale.copy = function() {
32445     return sequential(interpolator).domain([x0, x1]).clamp(clamp);
32446   };
32447
32448   return linearish(scale);
32449 }
32450
32451 var constant$10 = function(x) {
32452   return function constant() {
32453     return x;
32454   };
32455 };
32456
32457 var abs$1 = Math.abs;
32458 var atan2$1 = Math.atan2;
32459 var cos$2 = Math.cos;
32460 var max$2 = Math.max;
32461 var min$1 = Math.min;
32462 var sin$2 = Math.sin;
32463 var sqrt$2 = Math.sqrt;
32464
32465 var epsilon$3 = 1e-12;
32466 var pi$4 = Math.PI;
32467 var halfPi$3 = pi$4 / 2;
32468 var tau$4 = 2 * pi$4;
32469
32470 function acos$1(x) {
32471   return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
32472 }
32473
32474 function asin$1(x) {
32475   return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);
32476 }
32477
32478 function arcInnerRadius(d) {
32479   return d.innerRadius;
32480 }
32481
32482 function arcOuterRadius(d) {
32483   return d.outerRadius;
32484 }
32485
32486 function arcStartAngle(d) {
32487   return d.startAngle;
32488 }
32489
32490 function arcEndAngle(d) {
32491   return d.endAngle;
32492 }
32493
32494 function arcPadAngle(d) {
32495   return d && d.padAngle; // Note: optional!
32496 }
32497
32498 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
32499   var x10 = x1 - x0, y10 = y1 - y0,
32500       x32 = x3 - x2, y32 = y3 - y2,
32501       t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
32502   return [x0 + t * x10, y0 + t * y10];
32503 }
32504
32505 // Compute perpendicular offset line of length rc.
32506 // http://mathworld.wolfram.com/Circle-LineIntersection.html
32507 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
32508   var x01 = x0 - x1,
32509       y01 = y0 - y1,
32510       lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),
32511       ox = lo * y01,
32512       oy = -lo * x01,
32513       x11 = x0 + ox,
32514       y11 = y0 + oy,
32515       x10 = x1 + ox,
32516       y10 = y1 + oy,
32517       x00 = (x11 + x10) / 2,
32518       y00 = (y11 + y10) / 2,
32519       dx = x10 - x11,
32520       dy = y10 - y11,
32521       d2 = dx * dx + dy * dy,
32522       r = r1 - rc,
32523       D = x11 * y10 - x10 * y11,
32524       d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),
32525       cx0 = (D * dy - dx * d) / d2,
32526       cy0 = (-D * dx - dy * d) / d2,
32527       cx1 = (D * dy + dx * d) / d2,
32528       cy1 = (-D * dx + dy * d) / d2,
32529       dx0 = cx0 - x00,
32530       dy0 = cy0 - y00,
32531       dx1 = cx1 - x00,
32532       dy1 = cy1 - y00;
32533
32534   // Pick the closer of the two intersection points.
32535   // TODO Is there a faster way to determine which intersection to use?
32536   if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
32537
32538   return {
32539     cx: cx0,
32540     cy: cy0,
32541     x01: -ox,
32542     y01: -oy,
32543     x11: cx0 * (r1 / r - 1),
32544     y11: cy0 * (r1 / r - 1)
32545   };
32546 }
32547
32548 var arc = function() {
32549   var innerRadius = arcInnerRadius,
32550       outerRadius = arcOuterRadius,
32551       cornerRadius = constant$10(0),
32552       padRadius = null,
32553       startAngle = arcStartAngle,
32554       endAngle = arcEndAngle,
32555       padAngle = arcPadAngle,
32556       context = null;
32557
32558   function arc() {
32559     var buffer,
32560         r,
32561         r0 = +innerRadius.apply(this, arguments),
32562         r1 = +outerRadius.apply(this, arguments),
32563         a0 = startAngle.apply(this, arguments) - halfPi$3,
32564         a1 = endAngle.apply(this, arguments) - halfPi$3,
32565         da = abs$1(a1 - a0),
32566         cw = a1 > a0;
32567
32568     if (!context) context = buffer = path();
32569
32570     // Ensure that the outer radius is always larger than the inner radius.
32571     if (r1 < r0) r = r1, r1 = r0, r0 = r;
32572
32573     // Is it a point?
32574     if (!(r1 > epsilon$3)) context.moveTo(0, 0);
32575
32576     // Or is it a circle or annulus?
32577     else if (da > tau$4 - epsilon$3) {
32578       context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));
32579       context.arc(0, 0, r1, a0, a1, !cw);
32580       if (r0 > epsilon$3) {
32581         context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));
32582         context.arc(0, 0, r0, a1, a0, cw);
32583       }
32584     }
32585
32586     // Or is it a circular or annular sector?
32587     else {
32588       var a01 = a0,
32589           a11 = a1,
32590           a00 = a0,
32591           a10 = a1,
32592           da0 = da,
32593           da1 = da,
32594           ap = padAngle.apply(this, arguments) / 2,
32595           rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),
32596           rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
32597           rc0 = rc,
32598           rc1 = rc,
32599           t0,
32600           t1;
32601
32602       // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
32603       if (rp > epsilon$3) {
32604         var p0 = asin$1(rp / r0 * sin$2(ap)),
32605             p1 = asin$1(rp / r1 * sin$2(ap));
32606         if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
32607         else da0 = 0, a00 = a10 = (a0 + a1) / 2;
32608         if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
32609         else da1 = 0, a01 = a11 = (a0 + a1) / 2;
32610       }
32611
32612       var x01 = r1 * cos$2(a01),
32613           y01 = r1 * sin$2(a01),
32614           x10 = r0 * cos$2(a10),
32615           y10 = r0 * sin$2(a10);
32616
32617       // Apply rounded corners?
32618       if (rc > epsilon$3) {
32619         var x11 = r1 * cos$2(a11),
32620             y11 = r1 * sin$2(a11),
32621             x00 = r0 * cos$2(a00),
32622             y00 = r0 * sin$2(a00);
32623
32624         // Restrict the corner radius according to the sector angle.
32625         if (da < pi$4) {
32626           var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
32627               ax = x01 - oc[0],
32628               ay = y01 - oc[1],
32629               bx = x11 - oc[0],
32630               by = y11 - oc[1],
32631               kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),
32632               lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);
32633           rc0 = min$1(rc, (r0 - lc) / (kc - 1));
32634           rc1 = min$1(rc, (r1 - lc) / (kc + 1));
32635         }
32636       }
32637
32638       // Is the sector collapsed to a line?
32639       if (!(da1 > epsilon$3)) context.moveTo(x01, y01);
32640
32641       // Does the sector’s outer ring have rounded corners?
32642       else if (rc1 > epsilon$3) {
32643         t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
32644         t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
32645
32646         context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
32647
32648         // Have the corners merged?
32649         if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
32650
32651         // Otherwise, draw the two corners and the ring.
32652         else {
32653           context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
32654           context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
32655           context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
32656         }
32657       }
32658
32659       // Or is the outer ring just a circular arc?
32660       else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
32661
32662       // Is there no inner ring, and it’s a circular sector?
32663       // Or perhaps it’s an annular sector collapsed due to padding?
32664       if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);
32665
32666       // Does the sector’s inner ring (or point) have rounded corners?
32667       else if (rc0 > epsilon$3) {
32668         t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
32669         t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
32670
32671         context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
32672
32673         // Have the corners merged?
32674         if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
32675
32676         // Otherwise, draw the two corners and the ring.
32677         else {
32678           context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
32679           context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);
32680           context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
32681         }
32682       }
32683
32684       // Or is the inner ring just a circular arc?
32685       else context.arc(0, 0, r0, a10, a00, cw);
32686     }
32687
32688     context.closePath();
32689
32690     if (buffer) return context = null, buffer + "" || null;
32691   }
32692
32693   arc.centroid = function() {
32694     var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
32695         a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;
32696     return [cos$2(a) * r, sin$2(a) * r];
32697   };
32698
32699   arc.innerRadius = function(_) {
32700     return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : innerRadius;
32701   };
32702
32703   arc.outerRadius = function(_) {
32704     return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : outerRadius;
32705   };
32706
32707   arc.cornerRadius = function(_) {
32708     return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : cornerRadius;
32709   };
32710
32711   arc.padRadius = function(_) {
32712     return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), arc) : padRadius;
32713   };
32714
32715   arc.startAngle = function(_) {
32716     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : startAngle;
32717   };
32718
32719   arc.endAngle = function(_) {
32720     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : endAngle;
32721   };
32722
32723   arc.padAngle = function(_) {
32724     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : padAngle;
32725   };
32726
32727   arc.context = function(_) {
32728     return arguments.length ? ((context = _ == null ? null : _), arc) : context;
32729   };
32730
32731   return arc;
32732 };
32733
32734 function Linear(context) {
32735   this._context = context;
32736 }
32737
32738 Linear.prototype = {
32739   areaStart: function() {
32740     this._line = 0;
32741   },
32742   areaEnd: function() {
32743     this._line = NaN;
32744   },
32745   lineStart: function() {
32746     this._point = 0;
32747   },
32748   lineEnd: function() {
32749     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
32750     this._line = 1 - this._line;
32751   },
32752   point: function(x, y) {
32753     x = +x, y = +y;
32754     switch (this._point) {
32755       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
32756       case 1: this._point = 2; // proceed
32757       default: this._context.lineTo(x, y); break;
32758     }
32759   }
32760 };
32761
32762 var curveLinear = function(context) {
32763   return new Linear(context);
32764 };
32765
32766 function x$3(p) {
32767   return p[0];
32768 }
32769
32770 function y$3(p) {
32771   return p[1];
32772 }
32773
32774 var line = function() {
32775   var x = x$3,
32776       y = y$3,
32777       defined = constant$10(true),
32778       context = null,
32779       curve = curveLinear,
32780       output = null;
32781
32782   function line(data) {
32783     var i,
32784         n = data.length,
32785         d,
32786         defined0 = false,
32787         buffer;
32788
32789     if (context == null) output = curve(buffer = path());
32790
32791     for (i = 0; i <= n; ++i) {
32792       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
32793         if (defined0 = !defined0) output.lineStart();
32794         else output.lineEnd();
32795       }
32796       if (defined0) output.point(+x(d, i, data), +y(d, i, data));
32797     }
32798
32799     if (buffer) return output = null, buffer + "" || null;
32800   }
32801
32802   line.x = function(_) {
32803     return arguments.length ? (x = typeof _ === "function" ? _ : constant$10(+_), line) : x;
32804   };
32805
32806   line.y = function(_) {
32807     return arguments.length ? (y = typeof _ === "function" ? _ : constant$10(+_), line) : y;
32808   };
32809
32810   line.defined = function(_) {
32811     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), line) : defined;
32812   };
32813
32814   line.curve = function(_) {
32815     return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
32816   };
32817
32818   line.context = function(_) {
32819     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
32820   };
32821
32822   return line;
32823 };
32824
32825 var area$1 = function() {
32826   var x0 = x$3,
32827       x1 = null,
32828       y0 = constant$10(0),
32829       y1 = y$3,
32830       defined = constant$10(true),
32831       context = null,
32832       curve = curveLinear,
32833       output = null;
32834
32835   function area(data) {
32836     var i,
32837         j,
32838         k,
32839         n = data.length,
32840         d,
32841         defined0 = false,
32842         buffer,
32843         x0z = new Array(n),
32844         y0z = new Array(n);
32845
32846     if (context == null) output = curve(buffer = path());
32847
32848     for (i = 0; i <= n; ++i) {
32849       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
32850         if (defined0 = !defined0) {
32851           j = i;
32852           output.areaStart();
32853           output.lineStart();
32854         } else {
32855           output.lineEnd();
32856           output.lineStart();
32857           for (k = i - 1; k >= j; --k) {
32858             output.point(x0z[k], y0z[k]);
32859           }
32860           output.lineEnd();
32861           output.areaEnd();
32862         }
32863       }
32864       if (defined0) {
32865         x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
32866         output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
32867       }
32868     }
32869
32870     if (buffer) return output = null, buffer + "" || null;
32871   }
32872
32873   function arealine() {
32874     return line().defined(defined).curve(curve).context(context);
32875   }
32876
32877   area.x = function(_) {
32878     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), x1 = null, area) : x0;
32879   };
32880
32881   area.x0 = function(_) {
32882     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), area) : x0;
32883   };
32884
32885   area.x1 = function(_) {
32886     return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : x1;
32887   };
32888
32889   area.y = function(_) {
32890     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), y1 = null, area) : y0;
32891   };
32892
32893   area.y0 = function(_) {
32894     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), area) : y0;
32895   };
32896
32897   area.y1 = function(_) {
32898     return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : y1;
32899   };
32900
32901   area.lineX0 =
32902   area.lineY0 = function() {
32903     return arealine().x(x0).y(y0);
32904   };
32905
32906   area.lineY1 = function() {
32907     return arealine().x(x0).y(y1);
32908   };
32909
32910   area.lineX1 = function() {
32911     return arealine().x(x1).y(y0);
32912   };
32913
32914   area.defined = function(_) {
32915     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), area) : defined;
32916   };
32917
32918   area.curve = function(_) {
32919     return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
32920   };
32921
32922   area.context = function(_) {
32923     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
32924   };
32925
32926   return area;
32927 };
32928
32929 var descending$1 = function(a, b) {
32930   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
32931 };
32932
32933 var identity$7 = function(d) {
32934   return d;
32935 };
32936
32937 var pie = function() {
32938   var value = identity$7,
32939       sortValues = descending$1,
32940       sort = null,
32941       startAngle = constant$10(0),
32942       endAngle = constant$10(tau$4),
32943       padAngle = constant$10(0);
32944
32945   function pie(data) {
32946     var i,
32947         n = data.length,
32948         j,
32949         k,
32950         sum = 0,
32951         index = new Array(n),
32952         arcs = new Array(n),
32953         a0 = +startAngle.apply(this, arguments),
32954         da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),
32955         a1,
32956         p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
32957         pa = p * (da < 0 ? -1 : 1),
32958         v;
32959
32960     for (i = 0; i < n; ++i) {
32961       if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
32962         sum += v;
32963       }
32964     }
32965
32966     // Optionally sort the arcs by previously-computed values or by data.
32967     if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
32968     else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
32969
32970     // Compute the arcs! They are stored in the original data's order.
32971     for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
32972       j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
32973         data: data[j],
32974         index: i,
32975         value: v,
32976         startAngle: a0,
32977         endAngle: a1,
32978         padAngle: p
32979       };
32980     }
32981
32982     return arcs;
32983   }
32984
32985   pie.value = function(_) {
32986     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), pie) : value;
32987   };
32988
32989   pie.sortValues = function(_) {
32990     return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
32991   };
32992
32993   pie.sort = function(_) {
32994     return arguments.length ? (sort = _, sortValues = null, pie) : sort;
32995   };
32996
32997   pie.startAngle = function(_) {
32998     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : startAngle;
32999   };
33000
33001   pie.endAngle = function(_) {
33002     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : endAngle;
33003   };
33004
33005   pie.padAngle = function(_) {
33006     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : padAngle;
33007   };
33008
33009   return pie;
33010 };
33011
33012 var curveRadialLinear = curveRadial(curveLinear);
33013
33014 function Radial(curve) {
33015   this._curve = curve;
33016 }
33017
33018 Radial.prototype = {
33019   areaStart: function() {
33020     this._curve.areaStart();
33021   },
33022   areaEnd: function() {
33023     this._curve.areaEnd();
33024   },
33025   lineStart: function() {
33026     this._curve.lineStart();
33027   },
33028   lineEnd: function() {
33029     this._curve.lineEnd();
33030   },
33031   point: function(a, r) {
33032     this._curve.point(r * Math.sin(a), r * -Math.cos(a));
33033   }
33034 };
33035
33036 function curveRadial(curve) {
33037
33038   function radial(context) {
33039     return new Radial(curve(context));
33040   }
33041
33042   radial._curve = curve;
33043
33044   return radial;
33045 }
33046
33047 function lineRadial(l) {
33048   var c = l.curve;
33049
33050   l.angle = l.x, delete l.x;
33051   l.radius = l.y, delete l.y;
33052
33053   l.curve = function(_) {
33054     return arguments.length ? c(curveRadial(_)) : c()._curve;
33055   };
33056
33057   return l;
33058 }
33059
33060 var lineRadial$1 = function() {
33061   return lineRadial(line().curve(curveRadialLinear));
33062 };
33063
33064 var areaRadial = function() {
33065   var a = area$1().curve(curveRadialLinear),
33066       c = a.curve,
33067       x0 = a.lineX0,
33068       x1 = a.lineX1,
33069       y0 = a.lineY0,
33070       y1 = a.lineY1;
33071
33072   a.angle = a.x, delete a.x;
33073   a.startAngle = a.x0, delete a.x0;
33074   a.endAngle = a.x1, delete a.x1;
33075   a.radius = a.y, delete a.y;
33076   a.innerRadius = a.y0, delete a.y0;
33077   a.outerRadius = a.y1, delete a.y1;
33078   a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
33079   a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
33080   a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
33081   a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
33082
33083   a.curve = function(_) {
33084     return arguments.length ? c(curveRadial(_)) : c()._curve;
33085   };
33086
33087   return a;
33088 };
33089
33090 var pointRadial = function(x, y) {
33091   return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
33092 };
33093
33094 var slice$6 = Array.prototype.slice;
33095
33096 function linkSource(d) {
33097   return d.source;
33098 }
33099
33100 function linkTarget(d) {
33101   return d.target;
33102 }
33103
33104 function link$2(curve) {
33105   var source = linkSource,
33106       target = linkTarget,
33107       x = x$3,
33108       y = y$3,
33109       context = null;
33110
33111   function link() {
33112     var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);
33113     if (!context) context = buffer = path();
33114     curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));
33115     if (buffer) return context = null, buffer + "" || null;
33116   }
33117
33118   link.source = function(_) {
33119     return arguments.length ? (source = _, link) : source;
33120   };
33121
33122   link.target = function(_) {
33123     return arguments.length ? (target = _, link) : target;
33124   };
33125
33126   link.x = function(_) {
33127     return arguments.length ? (x = typeof _ === "function" ? _ : constant$10(+_), link) : x;
33128   };
33129
33130   link.y = function(_) {
33131     return arguments.length ? (y = typeof _ === "function" ? _ : constant$10(+_), link) : y;
33132   };
33133
33134   link.context = function(_) {
33135     return arguments.length ? ((context = _ == null ? null : _), link) : context;
33136   };
33137
33138   return link;
33139 }
33140
33141 function curveHorizontal(context, x0, y0, x1, y1) {
33142   context.moveTo(x0, y0);
33143   context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);
33144 }
33145
33146 function curveVertical(context, x0, y0, x1, y1) {
33147   context.moveTo(x0, y0);
33148   context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);
33149 }
33150
33151 function curveRadial$1(context, x0, y0, x1, y1) {
33152   var p0 = pointRadial(x0, y0),
33153       p1 = pointRadial(x0, y0 = (y0 + y1) / 2),
33154       p2 = pointRadial(x1, y0),
33155       p3 = pointRadial(x1, y1);
33156   context.moveTo(p0[0], p0[1]);
33157   context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
33158 }
33159
33160 function linkHorizontal() {
33161   return link$2(curveHorizontal);
33162 }
33163
33164 function linkVertical() {
33165   return link$2(curveVertical);
33166 }
33167
33168 function linkRadial() {
33169   var l = link$2(curveRadial$1);
33170   l.angle = l.x, delete l.x;
33171   l.radius = l.y, delete l.y;
33172   return l;
33173 }
33174
33175 var circle$2 = {
33176   draw: function(context, size) {
33177     var r = Math.sqrt(size / pi$4);
33178     context.moveTo(r, 0);
33179     context.arc(0, 0, r, 0, tau$4);
33180   }
33181 };
33182
33183 var cross$2 = {
33184   draw: function(context, size) {
33185     var r = Math.sqrt(size / 5) / 2;
33186     context.moveTo(-3 * r, -r);
33187     context.lineTo(-r, -r);
33188     context.lineTo(-r, -3 * r);
33189     context.lineTo(r, -3 * r);
33190     context.lineTo(r, -r);
33191     context.lineTo(3 * r, -r);
33192     context.lineTo(3 * r, r);
33193     context.lineTo(r, r);
33194     context.lineTo(r, 3 * r);
33195     context.lineTo(-r, 3 * r);
33196     context.lineTo(-r, r);
33197     context.lineTo(-3 * r, r);
33198     context.closePath();
33199   }
33200 };
33201
33202 var tan30 = Math.sqrt(1 / 3);
33203 var tan30_2 = tan30 * 2;
33204
33205 var diamond = {
33206   draw: function(context, size) {
33207     var y = Math.sqrt(size / tan30_2),
33208         x = y * tan30;
33209     context.moveTo(0, -y);
33210     context.lineTo(x, 0);
33211     context.lineTo(0, y);
33212     context.lineTo(-x, 0);
33213     context.closePath();
33214   }
33215 };
33216
33217 var ka = 0.89081309152928522810;
33218 var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);
33219 var kx = Math.sin(tau$4 / 10) * kr;
33220 var ky = -Math.cos(tau$4 / 10) * kr;
33221
33222 var star = {
33223   draw: function(context, size) {
33224     var r = Math.sqrt(size * ka),
33225         x = kx * r,
33226         y = ky * r;
33227     context.moveTo(0, -r);
33228     context.lineTo(x, y);
33229     for (var i = 1; i < 5; ++i) {
33230       var a = tau$4 * i / 5,
33231           c = Math.cos(a),
33232           s = Math.sin(a);
33233       context.lineTo(s * r, -c * r);
33234       context.lineTo(c * x - s * y, s * x + c * y);
33235     }
33236     context.closePath();
33237   }
33238 };
33239
33240 var square = {
33241   draw: function(context, size) {
33242     var w = Math.sqrt(size),
33243         x = -w / 2;
33244     context.rect(x, x, w, w);
33245   }
33246 };
33247
33248 var sqrt3 = Math.sqrt(3);
33249
33250 var triangle = {
33251   draw: function(context, size) {
33252     var y = -Math.sqrt(size / (sqrt3 * 3));
33253     context.moveTo(0, y * 2);
33254     context.lineTo(-sqrt3 * y, -y);
33255     context.lineTo(sqrt3 * y, -y);
33256     context.closePath();
33257   }
33258 };
33259
33260 var c = -0.5;
33261 var s = Math.sqrt(3) / 2;
33262 var k = 1 / Math.sqrt(12);
33263 var a = (k / 2 + 1) * 3;
33264
33265 var wye = {
33266   draw: function(context, size) {
33267     var r = Math.sqrt(size / a),
33268         x0 = r / 2,
33269         y0 = r * k,
33270         x1 = x0,
33271         y1 = r * k + r,
33272         x2 = -x1,
33273         y2 = y1;
33274     context.moveTo(x0, y0);
33275     context.lineTo(x1, y1);
33276     context.lineTo(x2, y2);
33277     context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
33278     context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
33279     context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
33280     context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
33281     context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
33282     context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
33283     context.closePath();
33284   }
33285 };
33286
33287 var symbols = [
33288   circle$2,
33289   cross$2,
33290   diamond,
33291   square,
33292   star,
33293   triangle,
33294   wye
33295 ];
33296
33297 var symbol = function() {
33298   var type = constant$10(circle$2),
33299       size = constant$10(64),
33300       context = null;
33301
33302   function symbol() {
33303     var buffer;
33304     if (!context) context = buffer = path();
33305     type.apply(this, arguments).draw(context, +size.apply(this, arguments));
33306     if (buffer) return context = null, buffer + "" || null;
33307   }
33308
33309   symbol.type = function(_) {
33310     return arguments.length ? (type = typeof _ === "function" ? _ : constant$10(_), symbol) : type;
33311   };
33312
33313   symbol.size = function(_) {
33314     return arguments.length ? (size = typeof _ === "function" ? _ : constant$10(+_), symbol) : size;
33315   };
33316
33317   symbol.context = function(_) {
33318     return arguments.length ? (context = _ == null ? null : _, symbol) : context;
33319   };
33320
33321   return symbol;
33322 };
33323
33324 var noop$2 = function() {};
33325
33326 function point$2(that, x, y) {
33327   that._context.bezierCurveTo(
33328     (2 * that._x0 + that._x1) / 3,
33329     (2 * that._y0 + that._y1) / 3,
33330     (that._x0 + 2 * that._x1) / 3,
33331     (that._y0 + 2 * that._y1) / 3,
33332     (that._x0 + 4 * that._x1 + x) / 6,
33333     (that._y0 + 4 * that._y1 + y) / 6
33334   );
33335 }
33336
33337 function Basis(context) {
33338   this._context = context;
33339 }
33340
33341 Basis.prototype = {
33342   areaStart: function() {
33343     this._line = 0;
33344   },
33345   areaEnd: function() {
33346     this._line = NaN;
33347   },
33348   lineStart: function() {
33349     this._x0 = this._x1 =
33350     this._y0 = this._y1 = NaN;
33351     this._point = 0;
33352   },
33353   lineEnd: function() {
33354     switch (this._point) {
33355       case 3: point$2(this, this._x1, this._y1); // proceed
33356       case 2: this._context.lineTo(this._x1, this._y1); break;
33357     }
33358     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33359     this._line = 1 - this._line;
33360   },
33361   point: function(x, y) {
33362     x = +x, y = +y;
33363     switch (this._point) {
33364       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33365       case 1: this._point = 2; break;
33366       case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
33367       default: point$2(this, x, y); break;
33368     }
33369     this._x0 = this._x1, this._x1 = x;
33370     this._y0 = this._y1, this._y1 = y;
33371   }
33372 };
33373
33374 var basis$2 = function(context) {
33375   return new Basis(context);
33376 };
33377
33378 function BasisClosed(context) {
33379   this._context = context;
33380 }
33381
33382 BasisClosed.prototype = {
33383   areaStart: noop$2,
33384   areaEnd: noop$2,
33385   lineStart: function() {
33386     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
33387     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
33388     this._point = 0;
33389   },
33390   lineEnd: function() {
33391     switch (this._point) {
33392       case 1: {
33393         this._context.moveTo(this._x2, this._y2);
33394         this._context.closePath();
33395         break;
33396       }
33397       case 2: {
33398         this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
33399         this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
33400         this._context.closePath();
33401         break;
33402       }
33403       case 3: {
33404         this.point(this._x2, this._y2);
33405         this.point(this._x3, this._y3);
33406         this.point(this._x4, this._y4);
33407         break;
33408       }
33409     }
33410   },
33411   point: function(x, y) {
33412     x = +x, y = +y;
33413     switch (this._point) {
33414       case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
33415       case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
33416       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;
33417       default: point$2(this, x, y); break;
33418     }
33419     this._x0 = this._x1, this._x1 = x;
33420     this._y0 = this._y1, this._y1 = y;
33421   }
33422 };
33423
33424 var basisClosed$1 = function(context) {
33425   return new BasisClosed(context);
33426 };
33427
33428 function BasisOpen(context) {
33429   this._context = context;
33430 }
33431
33432 BasisOpen.prototype = {
33433   areaStart: function() {
33434     this._line = 0;
33435   },
33436   areaEnd: function() {
33437     this._line = NaN;
33438   },
33439   lineStart: function() {
33440     this._x0 = this._x1 =
33441     this._y0 = this._y1 = NaN;
33442     this._point = 0;
33443   },
33444   lineEnd: function() {
33445     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
33446     this._line = 1 - this._line;
33447   },
33448   point: function(x, y) {
33449     x = +x, y = +y;
33450     switch (this._point) {
33451       case 0: this._point = 1; break;
33452       case 1: this._point = 2; break;
33453       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;
33454       case 3: this._point = 4; // proceed
33455       default: point$2(this, x, y); break;
33456     }
33457     this._x0 = this._x1, this._x1 = x;
33458     this._y0 = this._y1, this._y1 = y;
33459   }
33460 };
33461
33462 var basisOpen = function(context) {
33463   return new BasisOpen(context);
33464 };
33465
33466 function Bundle(context, beta) {
33467   this._basis = new Basis(context);
33468   this._beta = beta;
33469 }
33470
33471 Bundle.prototype = {
33472   lineStart: function() {
33473     this._x = [];
33474     this._y = [];
33475     this._basis.lineStart();
33476   },
33477   lineEnd: function() {
33478     var x = this._x,
33479         y = this._y,
33480         j = x.length - 1;
33481
33482     if (j > 0) {
33483       var x0 = x[0],
33484           y0 = y[0],
33485           dx = x[j] - x0,
33486           dy = y[j] - y0,
33487           i = -1,
33488           t;
33489
33490       while (++i <= j) {
33491         t = i / j;
33492         this._basis.point(
33493           this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
33494           this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
33495         );
33496       }
33497     }
33498
33499     this._x = this._y = null;
33500     this._basis.lineEnd();
33501   },
33502   point: function(x, y) {
33503     this._x.push(+x);
33504     this._y.push(+y);
33505   }
33506 };
33507
33508 var bundle = (function custom(beta) {
33509
33510   function bundle(context) {
33511     return beta === 1 ? new Basis(context) : new Bundle(context, beta);
33512   }
33513
33514   bundle.beta = function(beta) {
33515     return custom(+beta);
33516   };
33517
33518   return bundle;
33519 })(0.85);
33520
33521 function point$3(that, x, y) {
33522   that._context.bezierCurveTo(
33523     that._x1 + that._k * (that._x2 - that._x0),
33524     that._y1 + that._k * (that._y2 - that._y0),
33525     that._x2 + that._k * (that._x1 - x),
33526     that._y2 + that._k * (that._y1 - y),
33527     that._x2,
33528     that._y2
33529   );
33530 }
33531
33532 function Cardinal(context, tension) {
33533   this._context = context;
33534   this._k = (1 - tension) / 6;
33535 }
33536
33537 Cardinal.prototype = {
33538   areaStart: function() {
33539     this._line = 0;
33540   },
33541   areaEnd: function() {
33542     this._line = NaN;
33543   },
33544   lineStart: function() {
33545     this._x0 = this._x1 = this._x2 =
33546     this._y0 = this._y1 = this._y2 = NaN;
33547     this._point = 0;
33548   },
33549   lineEnd: function() {
33550     switch (this._point) {
33551       case 2: this._context.lineTo(this._x2, this._y2); break;
33552       case 3: point$3(this, this._x1, this._y1); break;
33553     }
33554     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33555     this._line = 1 - this._line;
33556   },
33557   point: function(x, y) {
33558     x = +x, y = +y;
33559     switch (this._point) {
33560       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33561       case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
33562       case 2: this._point = 3; // proceed
33563       default: point$3(this, x, y); break;
33564     }
33565     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33566     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33567   }
33568 };
33569
33570 var cardinal = (function custom(tension) {
33571
33572   function cardinal(context) {
33573     return new Cardinal(context, tension);
33574   }
33575
33576   cardinal.tension = function(tension) {
33577     return custom(+tension);
33578   };
33579
33580   return cardinal;
33581 })(0);
33582
33583 function CardinalClosed(context, tension) {
33584   this._context = context;
33585   this._k = (1 - tension) / 6;
33586 }
33587
33588 CardinalClosed.prototype = {
33589   areaStart: noop$2,
33590   areaEnd: noop$2,
33591   lineStart: function() {
33592     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
33593     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
33594     this._point = 0;
33595   },
33596   lineEnd: function() {
33597     switch (this._point) {
33598       case 1: {
33599         this._context.moveTo(this._x3, this._y3);
33600         this._context.closePath();
33601         break;
33602       }
33603       case 2: {
33604         this._context.lineTo(this._x3, this._y3);
33605         this._context.closePath();
33606         break;
33607       }
33608       case 3: {
33609         this.point(this._x3, this._y3);
33610         this.point(this._x4, this._y4);
33611         this.point(this._x5, this._y5);
33612         break;
33613       }
33614     }
33615   },
33616   point: function(x, y) {
33617     x = +x, y = +y;
33618     switch (this._point) {
33619       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
33620       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
33621       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
33622       default: point$3(this, x, y); break;
33623     }
33624     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33625     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33626   }
33627 };
33628
33629 var cardinalClosed = (function custom(tension) {
33630
33631   function cardinal$$1(context) {
33632     return new CardinalClosed(context, tension);
33633   }
33634
33635   cardinal$$1.tension = function(tension) {
33636     return custom(+tension);
33637   };
33638
33639   return cardinal$$1;
33640 })(0);
33641
33642 function CardinalOpen(context, tension) {
33643   this._context = context;
33644   this._k = (1 - tension) / 6;
33645 }
33646
33647 CardinalOpen.prototype = {
33648   areaStart: function() {
33649     this._line = 0;
33650   },
33651   areaEnd: function() {
33652     this._line = NaN;
33653   },
33654   lineStart: function() {
33655     this._x0 = this._x1 = this._x2 =
33656     this._y0 = this._y1 = this._y2 = NaN;
33657     this._point = 0;
33658   },
33659   lineEnd: function() {
33660     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
33661     this._line = 1 - this._line;
33662   },
33663   point: function(x, y) {
33664     x = +x, y = +y;
33665     switch (this._point) {
33666       case 0: this._point = 1; break;
33667       case 1: this._point = 2; break;
33668       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
33669       case 3: this._point = 4; // proceed
33670       default: point$3(this, x, y); break;
33671     }
33672     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33673     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33674   }
33675 };
33676
33677 var cardinalOpen = (function custom(tension) {
33678
33679   function cardinal$$1(context) {
33680     return new CardinalOpen(context, tension);
33681   }
33682
33683   cardinal$$1.tension = function(tension) {
33684     return custom(+tension);
33685   };
33686
33687   return cardinal$$1;
33688 })(0);
33689
33690 function point$4(that, x, y) {
33691   var x1 = that._x1,
33692       y1 = that._y1,
33693       x2 = that._x2,
33694       y2 = that._y2;
33695
33696   if (that._l01_a > epsilon$3) {
33697     var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
33698         n = 3 * that._l01_a * (that._l01_a + that._l12_a);
33699     x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
33700     y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
33701   }
33702
33703   if (that._l23_a > epsilon$3) {
33704     var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
33705         m = 3 * that._l23_a * (that._l23_a + that._l12_a);
33706     x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
33707     y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
33708   }
33709
33710   that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
33711 }
33712
33713 function CatmullRom(context, alpha) {
33714   this._context = context;
33715   this._alpha = alpha;
33716 }
33717
33718 CatmullRom.prototype = {
33719   areaStart: function() {
33720     this._line = 0;
33721   },
33722   areaEnd: function() {
33723     this._line = NaN;
33724   },
33725   lineStart: function() {
33726     this._x0 = this._x1 = this._x2 =
33727     this._y0 = this._y1 = this._y2 = NaN;
33728     this._l01_a = this._l12_a = this._l23_a =
33729     this._l01_2a = this._l12_2a = this._l23_2a =
33730     this._point = 0;
33731   },
33732   lineEnd: function() {
33733     switch (this._point) {
33734       case 2: this._context.lineTo(this._x2, this._y2); break;
33735       case 3: this.point(this._x2, this._y2); break;
33736     }
33737     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33738     this._line = 1 - this._line;
33739   },
33740   point: function(x, y) {
33741     x = +x, y = +y;
33742
33743     if (this._point) {
33744       var x23 = this._x2 - x,
33745           y23 = this._y2 - y;
33746       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
33747     }
33748
33749     switch (this._point) {
33750       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33751       case 1: this._point = 2; break;
33752       case 2: this._point = 3; // proceed
33753       default: point$4(this, x, y); break;
33754     }
33755
33756     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
33757     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
33758     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33759     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33760   }
33761 };
33762
33763 var catmullRom = (function custom(alpha) {
33764
33765   function catmullRom(context) {
33766     return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
33767   }
33768
33769   catmullRom.alpha = function(alpha) {
33770     return custom(+alpha);
33771   };
33772
33773   return catmullRom;
33774 })(0.5);
33775
33776 function CatmullRomClosed(context, alpha) {
33777   this._context = context;
33778   this._alpha = alpha;
33779 }
33780
33781 CatmullRomClosed.prototype = {
33782   areaStart: noop$2,
33783   areaEnd: noop$2,
33784   lineStart: function() {
33785     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
33786     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
33787     this._l01_a = this._l12_a = this._l23_a =
33788     this._l01_2a = this._l12_2a = this._l23_2a =
33789     this._point = 0;
33790   },
33791   lineEnd: function() {
33792     switch (this._point) {
33793       case 1: {
33794         this._context.moveTo(this._x3, this._y3);
33795         this._context.closePath();
33796         break;
33797       }
33798       case 2: {
33799         this._context.lineTo(this._x3, this._y3);
33800         this._context.closePath();
33801         break;
33802       }
33803       case 3: {
33804         this.point(this._x3, this._y3);
33805         this.point(this._x4, this._y4);
33806         this.point(this._x5, this._y5);
33807         break;
33808       }
33809     }
33810   },
33811   point: function(x, y) {
33812     x = +x, y = +y;
33813
33814     if (this._point) {
33815       var x23 = this._x2 - x,
33816           y23 = this._y2 - y;
33817       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
33818     }
33819
33820     switch (this._point) {
33821       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
33822       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
33823       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
33824       default: point$4(this, x, y); break;
33825     }
33826
33827     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
33828     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
33829     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33830     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33831   }
33832 };
33833
33834 var catmullRomClosed = (function custom(alpha) {
33835
33836   function catmullRom$$1(context) {
33837     return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
33838   }
33839
33840   catmullRom$$1.alpha = function(alpha) {
33841     return custom(+alpha);
33842   };
33843
33844   return catmullRom$$1;
33845 })(0.5);
33846
33847 function CatmullRomOpen(context, alpha) {
33848   this._context = context;
33849   this._alpha = alpha;
33850 }
33851
33852 CatmullRomOpen.prototype = {
33853   areaStart: function() {
33854     this._line = 0;
33855   },
33856   areaEnd: function() {
33857     this._line = NaN;
33858   },
33859   lineStart: function() {
33860     this._x0 = this._x1 = this._x2 =
33861     this._y0 = this._y1 = this._y2 = NaN;
33862     this._l01_a = this._l12_a = this._l23_a =
33863     this._l01_2a = this._l12_2a = this._l23_2a =
33864     this._point = 0;
33865   },
33866   lineEnd: function() {
33867     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
33868     this._line = 1 - this._line;
33869   },
33870   point: function(x, y) {
33871     x = +x, y = +y;
33872
33873     if (this._point) {
33874       var x23 = this._x2 - x,
33875           y23 = this._y2 - y;
33876       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
33877     }
33878
33879     switch (this._point) {
33880       case 0: this._point = 1; break;
33881       case 1: this._point = 2; break;
33882       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
33883       case 3: this._point = 4; // proceed
33884       default: point$4(this, x, y); break;
33885     }
33886
33887     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
33888     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
33889     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33890     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33891   }
33892 };
33893
33894 var catmullRomOpen = (function custom(alpha) {
33895
33896   function catmullRom$$1(context) {
33897     return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
33898   }
33899
33900   catmullRom$$1.alpha = function(alpha) {
33901     return custom(+alpha);
33902   };
33903
33904   return catmullRom$$1;
33905 })(0.5);
33906
33907 function LinearClosed(context) {
33908   this._context = context;
33909 }
33910
33911 LinearClosed.prototype = {
33912   areaStart: noop$2,
33913   areaEnd: noop$2,
33914   lineStart: function() {
33915     this._point = 0;
33916   },
33917   lineEnd: function() {
33918     if (this._point) this._context.closePath();
33919   },
33920   point: function(x, y) {
33921     x = +x, y = +y;
33922     if (this._point) this._context.lineTo(x, y);
33923     else this._point = 1, this._context.moveTo(x, y);
33924   }
33925 };
33926
33927 var linearClosed = function(context) {
33928   return new LinearClosed(context);
33929 };
33930
33931 function sign$1(x) {
33932   return x < 0 ? -1 : 1;
33933 }
33934
33935 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
33936 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
33937 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
33938 // NOV(II), P. 443, 1990.
33939 function slope3(that, x2, y2) {
33940   var h0 = that._x1 - that._x0,
33941       h1 = x2 - that._x1,
33942       s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
33943       s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
33944       p = (s0 * h1 + s1 * h0) / (h0 + h1);
33945   return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
33946 }
33947
33948 // Calculate a one-sided slope.
33949 function slope2(that, t) {
33950   var h = that._x1 - that._x0;
33951   return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
33952 }
33953
33954 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
33955 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
33956 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
33957 function point$5(that, t0, t1) {
33958   var x0 = that._x0,
33959       y0 = that._y0,
33960       x1 = that._x1,
33961       y1 = that._y1,
33962       dx = (x1 - x0) / 3;
33963   that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
33964 }
33965
33966 function MonotoneX(context) {
33967   this._context = context;
33968 }
33969
33970 MonotoneX.prototype = {
33971   areaStart: function() {
33972     this._line = 0;
33973   },
33974   areaEnd: function() {
33975     this._line = NaN;
33976   },
33977   lineStart: function() {
33978     this._x0 = this._x1 =
33979     this._y0 = this._y1 =
33980     this._t0 = NaN;
33981     this._point = 0;
33982   },
33983   lineEnd: function() {
33984     switch (this._point) {
33985       case 2: this._context.lineTo(this._x1, this._y1); break;
33986       case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
33987     }
33988     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33989     this._line = 1 - this._line;
33990   },
33991   point: function(x, y) {
33992     var t1 = NaN;
33993
33994     x = +x, y = +y;
33995     if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
33996     switch (this._point) {
33997       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33998       case 1: this._point = 2; break;
33999       case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
34000       default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;
34001     }
34002
34003     this._x0 = this._x1, this._x1 = x;
34004     this._y0 = this._y1, this._y1 = y;
34005     this._t0 = t1;
34006   }
34007 };
34008
34009 function MonotoneY(context) {
34010   this._context = new ReflectContext(context);
34011 }
34012
34013 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
34014   MonotoneX.prototype.point.call(this, y, x);
34015 };
34016
34017 function ReflectContext(context) {
34018   this._context = context;
34019 }
34020
34021 ReflectContext.prototype = {
34022   moveTo: function(x, y) { this._context.moveTo(y, x); },
34023   closePath: function() { this._context.closePath(); },
34024   lineTo: function(x, y) { this._context.lineTo(y, x); },
34025   bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
34026 };
34027
34028 function monotoneX(context) {
34029   return new MonotoneX(context);
34030 }
34031
34032 function monotoneY(context) {
34033   return new MonotoneY(context);
34034 }
34035
34036 function Natural(context) {
34037   this._context = context;
34038 }
34039
34040 Natural.prototype = {
34041   areaStart: function() {
34042     this._line = 0;
34043   },
34044   areaEnd: function() {
34045     this._line = NaN;
34046   },
34047   lineStart: function() {
34048     this._x = [];
34049     this._y = [];
34050   },
34051   lineEnd: function() {
34052     var x = this._x,
34053         y = this._y,
34054         n = x.length;
34055
34056     if (n) {
34057       this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
34058       if (n === 2) {
34059         this._context.lineTo(x[1], y[1]);
34060       } else {
34061         var px = controlPoints(x),
34062             py = controlPoints(y);
34063         for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
34064           this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
34065         }
34066       }
34067     }
34068
34069     if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
34070     this._line = 1 - this._line;
34071     this._x = this._y = null;
34072   },
34073   point: function(x, y) {
34074     this._x.push(+x);
34075     this._y.push(+y);
34076   }
34077 };
34078
34079 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
34080 function controlPoints(x) {
34081   var i,
34082       n = x.length - 1,
34083       m,
34084       a = new Array(n),
34085       b = new Array(n),
34086       r = new Array(n);
34087   a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
34088   for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
34089   a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
34090   for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
34091   a[n - 1] = r[n - 1] / b[n - 1];
34092   for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
34093   b[n - 1] = (x[n] + a[n - 1]) / 2;
34094   for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
34095   return [a, b];
34096 }
34097
34098 var natural = function(context) {
34099   return new Natural(context);
34100 };
34101
34102 function Step(context, t) {
34103   this._context = context;
34104   this._t = t;
34105 }
34106
34107 Step.prototype = {
34108   areaStart: function() {
34109     this._line = 0;
34110   },
34111   areaEnd: function() {
34112     this._line = NaN;
34113   },
34114   lineStart: function() {
34115     this._x = this._y = NaN;
34116     this._point = 0;
34117   },
34118   lineEnd: function() {
34119     if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
34120     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
34121     if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
34122   },
34123   point: function(x, y) {
34124     x = +x, y = +y;
34125     switch (this._point) {
34126       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
34127       case 1: this._point = 2; // proceed
34128       default: {
34129         if (this._t <= 0) {
34130           this._context.lineTo(this._x, y);
34131           this._context.lineTo(x, y);
34132         } else {
34133           var x1 = this._x * (1 - this._t) + x * this._t;
34134           this._context.lineTo(x1, this._y);
34135           this._context.lineTo(x1, y);
34136         }
34137         break;
34138       }
34139     }
34140     this._x = x, this._y = y;
34141   }
34142 };
34143
34144 var step = function(context) {
34145   return new Step(context, 0.5);
34146 };
34147
34148 function stepBefore(context) {
34149   return new Step(context, 0);
34150 }
34151
34152 function stepAfter(context) {
34153   return new Step(context, 1);
34154 }
34155
34156 var none$1 = function(series, order) {
34157   if (!((n = series.length) > 1)) return;
34158   for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
34159     s0 = s1, s1 = series[order[i]];
34160     for (j = 0; j < m; ++j) {
34161       s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
34162     }
34163   }
34164 };
34165
34166 var none$2 = function(series) {
34167   var n = series.length, o = new Array(n);
34168   while (--n >= 0) o[n] = n;
34169   return o;
34170 };
34171
34172 function stackValue(d, key) {
34173   return d[key];
34174 }
34175
34176 var stack = function() {
34177   var keys = constant$10([]),
34178       order = none$2,
34179       offset = none$1,
34180       value = stackValue;
34181
34182   function stack(data) {
34183     var kz = keys.apply(this, arguments),
34184         i,
34185         m = data.length,
34186         n = kz.length,
34187         sz = new Array(n),
34188         oz;
34189
34190     for (i = 0; i < n; ++i) {
34191       for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
34192         si[j] = sij = [0, +value(data[j], ki, j, data)];
34193         sij.data = data[j];
34194       }
34195       si.key = ki;
34196     }
34197
34198     for (i = 0, oz = order(sz); i < n; ++i) {
34199       sz[oz[i]].index = i;
34200     }
34201
34202     offset(sz, oz);
34203     return sz;
34204   }
34205
34206   stack.keys = function(_) {
34207     return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : keys;
34208   };
34209
34210   stack.value = function(_) {
34211     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), stack) : value;
34212   };
34213
34214   stack.order = function(_) {
34215     return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : order;
34216   };
34217
34218   stack.offset = function(_) {
34219     return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
34220   };
34221
34222   return stack;
34223 };
34224
34225 var expand = function(series, order) {
34226   if (!((n = series.length) > 0)) return;
34227   for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
34228     for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
34229     if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
34230   }
34231   none$1(series, order);
34232 };
34233
34234 var diverging = function(series, order) {
34235   if (!((n = series.length) > 1)) return;
34236   for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
34237     for (yp = yn = 0, i = 0; i < n; ++i) {
34238       if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {
34239         d[0] = yp, d[1] = yp += dy;
34240       } else if (dy < 0) {
34241         d[1] = yn, d[0] = yn += dy;
34242       } else {
34243         d[0] = yp;
34244       }
34245     }
34246   }
34247 };
34248
34249 var silhouette = function(series, order) {
34250   if (!((n = series.length) > 0)) return;
34251   for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
34252     for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
34253     s0[j][1] += s0[j][0] = -y / 2;
34254   }
34255   none$1(series, order);
34256 };
34257
34258 var wiggle = function(series, order) {
34259   if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
34260   for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
34261     for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
34262       var si = series[order[i]],
34263           sij0 = si[j][1] || 0,
34264           sij1 = si[j - 1][1] || 0,
34265           s3 = (sij0 - sij1) / 2;
34266       for (var k = 0; k < i; ++k) {
34267         var sk = series[order[k]],
34268             skj0 = sk[j][1] || 0,
34269             skj1 = sk[j - 1][1] || 0;
34270         s3 += skj0 - skj1;
34271       }
34272       s1 += sij0, s2 += s3 * sij0;
34273     }
34274     s0[j - 1][1] += s0[j - 1][0] = y;
34275     if (s1) y -= s2 / s1;
34276   }
34277   s0[j - 1][1] += s0[j - 1][0] = y;
34278   none$1(series, order);
34279 };
34280
34281 var ascending$2 = function(series) {
34282   var sums = series.map(sum$2);
34283   return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
34284 };
34285
34286 function sum$2(series) {
34287   var s = 0, i = -1, n = series.length, v;
34288   while (++i < n) if (v = +series[i][1]) s += v;
34289   return s;
34290 }
34291
34292 var descending$2 = function(series) {
34293   return ascending$2(series).reverse();
34294 };
34295
34296 var insideOut = function(series) {
34297   var n = series.length,
34298       i,
34299       j,
34300       sums = series.map(sum$2),
34301       order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),
34302       top = 0,
34303       bottom = 0,
34304       tops = [],
34305       bottoms = [];
34306
34307   for (i = 0; i < n; ++i) {
34308     j = order[i];
34309     if (top < bottom) {
34310       top += sums[j];
34311       tops.push(j);
34312     } else {
34313       bottom += sums[j];
34314       bottoms.push(j);
34315     }
34316   }
34317
34318   return bottoms.reverse().concat(tops);
34319 };
34320
34321 var reverse = function(series) {
34322   return none$2(series).reverse();
34323 };
34324
34325 var constant$11 = function(x) {
34326   return function() {
34327     return x;
34328   };
34329 };
34330
34331 function x$4(d) {
34332   return d[0];
34333 }
34334
34335 function y$4(d) {
34336   return d[1];
34337 }
34338
34339 function RedBlackTree() {
34340   this._ = null; // root node
34341 }
34342
34343 function RedBlackNode(node) {
34344   node.U = // parent node
34345   node.C = // color - true for red, false for black
34346   node.L = // left node
34347   node.R = // right node
34348   node.P = // previous node
34349   node.N = null; // next node
34350 }
34351
34352 RedBlackTree.prototype = {
34353   constructor: RedBlackTree,
34354
34355   insert: function(after, node) {
34356     var parent, grandpa, uncle;
34357
34358     if (after) {
34359       node.P = after;
34360       node.N = after.N;
34361       if (after.N) after.N.P = node;
34362       after.N = node;
34363       if (after.R) {
34364         after = after.R;
34365         while (after.L) after = after.L;
34366         after.L = node;
34367       } else {
34368         after.R = node;
34369       }
34370       parent = after;
34371     } else if (this._) {
34372       after = RedBlackFirst(this._);
34373       node.P = null;
34374       node.N = after;
34375       after.P = after.L = node;
34376       parent = after;
34377     } else {
34378       node.P = node.N = null;
34379       this._ = node;
34380       parent = null;
34381     }
34382     node.L = node.R = null;
34383     node.U = parent;
34384     node.C = true;
34385
34386     after = node;
34387     while (parent && parent.C) {
34388       grandpa = parent.U;
34389       if (parent === grandpa.L) {
34390         uncle = grandpa.R;
34391         if (uncle && uncle.C) {
34392           parent.C = uncle.C = false;
34393           grandpa.C = true;
34394           after = grandpa;
34395         } else {
34396           if (after === parent.R) {
34397             RedBlackRotateLeft(this, parent);
34398             after = parent;
34399             parent = after.U;
34400           }
34401           parent.C = false;
34402           grandpa.C = true;
34403           RedBlackRotateRight(this, grandpa);
34404         }
34405       } else {
34406         uncle = grandpa.L;
34407         if (uncle && uncle.C) {
34408           parent.C = uncle.C = false;
34409           grandpa.C = true;
34410           after = grandpa;
34411         } else {
34412           if (after === parent.L) {
34413             RedBlackRotateRight(this, parent);
34414             after = parent;
34415             parent = after.U;
34416           }
34417           parent.C = false;
34418           grandpa.C = true;
34419           RedBlackRotateLeft(this, grandpa);
34420         }
34421       }
34422       parent = after.U;
34423     }
34424     this._.C = false;
34425   },
34426
34427   remove: function(node) {
34428     if (node.N) node.N.P = node.P;
34429     if (node.P) node.P.N = node.N;
34430     node.N = node.P = null;
34431
34432     var parent = node.U,
34433         sibling,
34434         left = node.L,
34435         right = node.R,
34436         next,
34437         red;
34438
34439     if (!left) next = right;
34440     else if (!right) next = left;
34441     else next = RedBlackFirst(right);
34442
34443     if (parent) {
34444       if (parent.L === node) parent.L = next;
34445       else parent.R = next;
34446     } else {
34447       this._ = next;
34448     }
34449
34450     if (left && right) {
34451       red = next.C;
34452       next.C = node.C;
34453       next.L = left;
34454       left.U = next;
34455       if (next !== right) {
34456         parent = next.U;
34457         next.U = node.U;
34458         node = next.R;
34459         parent.L = node;
34460         next.R = right;
34461         right.U = next;
34462       } else {
34463         next.U = parent;
34464         parent = next;
34465         node = next.R;
34466       }
34467     } else {
34468       red = node.C;
34469       node = next;
34470     }
34471
34472     if (node) node.U = parent;
34473     if (red) return;
34474     if (node && node.C) { node.C = false; return; }
34475
34476     do {
34477       if (node === this._) break;
34478       if (node === parent.L) {
34479         sibling = parent.R;
34480         if (sibling.C) {
34481           sibling.C = false;
34482           parent.C = true;
34483           RedBlackRotateLeft(this, parent);
34484           sibling = parent.R;
34485         }
34486         if ((sibling.L && sibling.L.C)
34487             || (sibling.R && sibling.R.C)) {
34488           if (!sibling.R || !sibling.R.C) {
34489             sibling.L.C = false;
34490             sibling.C = true;
34491             RedBlackRotateRight(this, sibling);
34492             sibling = parent.R;
34493           }
34494           sibling.C = parent.C;
34495           parent.C = sibling.R.C = false;
34496           RedBlackRotateLeft(this, parent);
34497           node = this._;
34498           break;
34499         }
34500       } else {
34501         sibling = parent.L;
34502         if (sibling.C) {
34503           sibling.C = false;
34504           parent.C = true;
34505           RedBlackRotateRight(this, parent);
34506           sibling = parent.L;
34507         }
34508         if ((sibling.L && sibling.L.C)
34509           || (sibling.R && sibling.R.C)) {
34510           if (!sibling.L || !sibling.L.C) {
34511             sibling.R.C = false;
34512             sibling.C = true;
34513             RedBlackRotateLeft(this, sibling);
34514             sibling = parent.L;
34515           }
34516           sibling.C = parent.C;
34517           parent.C = sibling.L.C = false;
34518           RedBlackRotateRight(this, parent);
34519           node = this._;
34520           break;
34521         }
34522       }
34523       sibling.C = true;
34524       node = parent;
34525       parent = parent.U;
34526     } while (!node.C);
34527
34528     if (node) node.C = false;
34529   }
34530 };
34531
34532 function RedBlackRotateLeft(tree, node) {
34533   var p = node,
34534       q = node.R,
34535       parent = p.U;
34536
34537   if (parent) {
34538     if (parent.L === p) parent.L = q;
34539     else parent.R = q;
34540   } else {
34541     tree._ = q;
34542   }
34543
34544   q.U = parent;
34545   p.U = q;
34546   p.R = q.L;
34547   if (p.R) p.R.U = p;
34548   q.L = p;
34549 }
34550
34551 function RedBlackRotateRight(tree, node) {
34552   var p = node,
34553       q = node.L,
34554       parent = p.U;
34555
34556   if (parent) {
34557     if (parent.L === p) parent.L = q;
34558     else parent.R = q;
34559   } else {
34560     tree._ = q;
34561   }
34562
34563   q.U = parent;
34564   p.U = q;
34565   p.L = q.R;
34566   if (p.L) p.L.U = p;
34567   q.R = p;
34568 }
34569
34570 function RedBlackFirst(node) {
34571   while (node.L) node = node.L;
34572   return node;
34573 }
34574
34575 function createEdge(left, right, v0, v1) {
34576   var edge = [null, null],
34577       index = edges.push(edge) - 1;
34578   edge.left = left;
34579   edge.right = right;
34580   if (v0) setEdgeEnd(edge, left, right, v0);
34581   if (v1) setEdgeEnd(edge, right, left, v1);
34582   cells[left.index].halfedges.push(index);
34583   cells[right.index].halfedges.push(index);
34584   return edge;
34585 }
34586
34587 function createBorderEdge(left, v0, v1) {
34588   var edge = [v0, v1];
34589   edge.left = left;
34590   return edge;
34591 }
34592
34593 function setEdgeEnd(edge, left, right, vertex) {
34594   if (!edge[0] && !edge[1]) {
34595     edge[0] = vertex;
34596     edge.left = left;
34597     edge.right = right;
34598   } else if (edge.left === right) {
34599     edge[1] = vertex;
34600   } else {
34601     edge[0] = vertex;
34602   }
34603 }
34604
34605 // Liang–Barsky line clipping.
34606 function clipEdge(edge, x0, y0, x1, y1) {
34607   var a = edge[0],
34608       b = edge[1],
34609       ax = a[0],
34610       ay = a[1],
34611       bx = b[0],
34612       by = b[1],
34613       t0 = 0,
34614       t1 = 1,
34615       dx = bx - ax,
34616       dy = by - ay,
34617       r;
34618
34619   r = x0 - ax;
34620   if (!dx && r > 0) return;
34621   r /= dx;
34622   if (dx < 0) {
34623     if (r < t0) return;
34624     if (r < t1) t1 = r;
34625   } else if (dx > 0) {
34626     if (r > t1) return;
34627     if (r > t0) t0 = r;
34628   }
34629
34630   r = x1 - ax;
34631   if (!dx && r < 0) return;
34632   r /= dx;
34633   if (dx < 0) {
34634     if (r > t1) return;
34635     if (r > t0) t0 = r;
34636   } else if (dx > 0) {
34637     if (r < t0) return;
34638     if (r < t1) t1 = r;
34639   }
34640
34641   r = y0 - ay;
34642   if (!dy && r > 0) return;
34643   r /= dy;
34644   if (dy < 0) {
34645     if (r < t0) return;
34646     if (r < t1) t1 = r;
34647   } else if (dy > 0) {
34648     if (r > t1) return;
34649     if (r > t0) t0 = r;
34650   }
34651
34652   r = y1 - ay;
34653   if (!dy && r < 0) return;
34654   r /= dy;
34655   if (dy < 0) {
34656     if (r > t1) return;
34657     if (r > t0) t0 = r;
34658   } else if (dy > 0) {
34659     if (r < t0) return;
34660     if (r < t1) t1 = r;
34661   }
34662
34663   if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
34664
34665   if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
34666   if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
34667   return true;
34668 }
34669
34670 function connectEdge(edge, x0, y0, x1, y1) {
34671   var v1 = edge[1];
34672   if (v1) return true;
34673
34674   var v0 = edge[0],
34675       left = edge.left,
34676       right = edge.right,
34677       lx = left[0],
34678       ly = left[1],
34679       rx = right[0],
34680       ry = right[1],
34681       fx = (lx + rx) / 2,
34682       fy = (ly + ry) / 2,
34683       fm,
34684       fb;
34685
34686   if (ry === ly) {
34687     if (fx < x0 || fx >= x1) return;
34688     if (lx > rx) {
34689       if (!v0) v0 = [fx, y0];
34690       else if (v0[1] >= y1) return;
34691       v1 = [fx, y1];
34692     } else {
34693       if (!v0) v0 = [fx, y1];
34694       else if (v0[1] < y0) return;
34695       v1 = [fx, y0];
34696     }
34697   } else {
34698     fm = (lx - rx) / (ry - ly);
34699     fb = fy - fm * fx;
34700     if (fm < -1 || fm > 1) {
34701       if (lx > rx) {
34702         if (!v0) v0 = [(y0 - fb) / fm, y0];
34703         else if (v0[1] >= y1) return;
34704         v1 = [(y1 - fb) / fm, y1];
34705       } else {
34706         if (!v0) v0 = [(y1 - fb) / fm, y1];
34707         else if (v0[1] < y0) return;
34708         v1 = [(y0 - fb) / fm, y0];
34709       }
34710     } else {
34711       if (ly < ry) {
34712         if (!v0) v0 = [x0, fm * x0 + fb];
34713         else if (v0[0] >= x1) return;
34714         v1 = [x1, fm * x1 + fb];
34715       } else {
34716         if (!v0) v0 = [x1, fm * x1 + fb];
34717         else if (v0[0] < x0) return;
34718         v1 = [x0, fm * x0 + fb];
34719       }
34720     }
34721   }
34722
34723   edge[0] = v0;
34724   edge[1] = v1;
34725   return true;
34726 }
34727
34728 function clipEdges(x0, y0, x1, y1) {
34729   var i = edges.length,
34730       edge;
34731
34732   while (i--) {
34733     if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
34734         || !clipEdge(edge, x0, y0, x1, y1)
34735         || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
34736             || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
34737       delete edges[i];
34738     }
34739   }
34740 }
34741
34742 function createCell(site) {
34743   return cells[site.index] = {
34744     site: site,
34745     halfedges: []
34746   };
34747 }
34748
34749 function cellHalfedgeAngle(cell, edge) {
34750   var site = cell.site,
34751       va = edge.left,
34752       vb = edge.right;
34753   if (site === vb) vb = va, va = site;
34754   if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
34755   if (site === va) va = edge[1], vb = edge[0];
34756   else va = edge[0], vb = edge[1];
34757   return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
34758 }
34759
34760 function cellHalfedgeStart(cell, edge) {
34761   return edge[+(edge.left !== cell.site)];
34762 }
34763
34764 function cellHalfedgeEnd(cell, edge) {
34765   return edge[+(edge.left === cell.site)];
34766 }
34767
34768 function sortCellHalfedges() {
34769   for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
34770     if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
34771       var index = new Array(m),
34772           array = new Array(m);
34773       for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
34774       index.sort(function(i, j) { return array[j] - array[i]; });
34775       for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
34776       for (j = 0; j < m; ++j) halfedges[j] = array[j];
34777     }
34778   }
34779 }
34780
34781 function clipCells(x0, y0, x1, y1) {
34782   var nCells = cells.length,
34783       iCell,
34784       cell,
34785       site,
34786       iHalfedge,
34787       halfedges,
34788       nHalfedges,
34789       start,
34790       startX,
34791       startY,
34792       end,
34793       endX,
34794       endY,
34795       cover = true;
34796
34797   for (iCell = 0; iCell < nCells; ++iCell) {
34798     if (cell = cells[iCell]) {
34799       site = cell.site;
34800       halfedges = cell.halfedges;
34801       iHalfedge = halfedges.length;
34802
34803       // Remove any dangling clipped edges.
34804       while (iHalfedge--) {
34805         if (!edges[halfedges[iHalfedge]]) {
34806           halfedges.splice(iHalfedge, 1);
34807         }
34808       }
34809
34810       // Insert any border edges as necessary.
34811       iHalfedge = 0, nHalfedges = halfedges.length;
34812       while (iHalfedge < nHalfedges) {
34813         end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
34814         start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
34815         if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {
34816           halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
34817               Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
34818               : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
34819               : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
34820               : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
34821               : null)) - 1);
34822           ++nHalfedges;
34823         }
34824       }
34825
34826       if (nHalfedges) cover = false;
34827     }
34828   }
34829
34830   // If there weren’t any edges, have the closest site cover the extent.
34831   // It doesn’t matter which corner of the extent we measure!
34832   if (cover) {
34833     var dx, dy, d2, dc = Infinity;
34834
34835     for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
34836       if (cell = cells[iCell]) {
34837         site = cell.site;
34838         dx = site[0] - x0;
34839         dy = site[1] - y0;
34840         d2 = dx * dx + dy * dy;
34841         if (d2 < dc) dc = d2, cover = cell;
34842       }
34843     }
34844
34845     if (cover) {
34846       var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
34847       cover.halfedges.push(
34848         edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
34849         edges.push(createBorderEdge(site, v01, v11)) - 1,
34850         edges.push(createBorderEdge(site, v11, v10)) - 1,
34851         edges.push(createBorderEdge(site, v10, v00)) - 1
34852       );
34853     }
34854   }
34855
34856   // Lastly delete any cells with no edges; these were entirely clipped.
34857   for (iCell = 0; iCell < nCells; ++iCell) {
34858     if (cell = cells[iCell]) {
34859       if (!cell.halfedges.length) {
34860         delete cells[iCell];
34861       }
34862     }
34863   }
34864 }
34865
34866 var circlePool = [];
34867
34868 var firstCircle;
34869
34870 function Circle() {
34871   RedBlackNode(this);
34872   this.x =
34873   this.y =
34874   this.arc =
34875   this.site =
34876   this.cy = null;
34877 }
34878
34879 function attachCircle(arc) {
34880   var lArc = arc.P,
34881       rArc = arc.N;
34882
34883   if (!lArc || !rArc) return;
34884
34885   var lSite = lArc.site,
34886       cSite = arc.site,
34887       rSite = rArc.site;
34888
34889   if (lSite === rSite) return;
34890
34891   var bx = cSite[0],
34892       by = cSite[1],
34893       ax = lSite[0] - bx,
34894       ay = lSite[1] - by,
34895       cx = rSite[0] - bx,
34896       cy = rSite[1] - by;
34897
34898   var d = 2 * (ax * cy - ay * cx);
34899   if (d >= -epsilon2$2) return;
34900
34901   var ha = ax * ax + ay * ay,
34902       hc = cx * cx + cy * cy,
34903       x = (cy * ha - ay * hc) / d,
34904       y = (ax * hc - cx * ha) / d;
34905
34906   var circle = circlePool.pop() || new Circle;
34907   circle.arc = arc;
34908   circle.site = cSite;
34909   circle.x = x + bx;
34910   circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
34911
34912   arc.circle = circle;
34913
34914   var before = null,
34915       node = circles._;
34916
34917   while (node) {
34918     if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
34919       if (node.L) node = node.L;
34920       else { before = node.P; break; }
34921     } else {
34922       if (node.R) node = node.R;
34923       else { before = node; break; }
34924     }
34925   }
34926
34927   circles.insert(before, circle);
34928   if (!before) firstCircle = circle;
34929 }
34930
34931 function detachCircle(arc) {
34932   var circle = arc.circle;
34933   if (circle) {
34934     if (!circle.P) firstCircle = circle.N;
34935     circles.remove(circle);
34936     circlePool.push(circle);
34937     RedBlackNode(circle);
34938     arc.circle = null;
34939   }
34940 }
34941
34942 var beachPool = [];
34943
34944 function Beach() {
34945   RedBlackNode(this);
34946   this.edge =
34947   this.site =
34948   this.circle = null;
34949 }
34950
34951 function createBeach(site) {
34952   var beach = beachPool.pop() || new Beach;
34953   beach.site = site;
34954   return beach;
34955 }
34956
34957 function detachBeach(beach) {
34958   detachCircle(beach);
34959   beaches.remove(beach);
34960   beachPool.push(beach);
34961   RedBlackNode(beach);
34962 }
34963
34964 function removeBeach(beach) {
34965   var circle = beach.circle,
34966       x = circle.x,
34967       y = circle.cy,
34968       vertex = [x, y],
34969       previous = beach.P,
34970       next = beach.N,
34971       disappearing = [beach];
34972
34973   detachBeach(beach);
34974
34975   var lArc = previous;
34976   while (lArc.circle
34977       && Math.abs(x - lArc.circle.x) < epsilon$4
34978       && Math.abs(y - lArc.circle.cy) < epsilon$4) {
34979     previous = lArc.P;
34980     disappearing.unshift(lArc);
34981     detachBeach(lArc);
34982     lArc = previous;
34983   }
34984
34985   disappearing.unshift(lArc);
34986   detachCircle(lArc);
34987
34988   var rArc = next;
34989   while (rArc.circle
34990       && Math.abs(x - rArc.circle.x) < epsilon$4
34991       && Math.abs(y - rArc.circle.cy) < epsilon$4) {
34992     next = rArc.N;
34993     disappearing.push(rArc);
34994     detachBeach(rArc);
34995     rArc = next;
34996   }
34997
34998   disappearing.push(rArc);
34999   detachCircle(rArc);
35000
35001   var nArcs = disappearing.length,
35002       iArc;
35003   for (iArc = 1; iArc < nArcs; ++iArc) {
35004     rArc = disappearing[iArc];
35005     lArc = disappearing[iArc - 1];
35006     setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
35007   }
35008
35009   lArc = disappearing[0];
35010   rArc = disappearing[nArcs - 1];
35011   rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
35012
35013   attachCircle(lArc);
35014   attachCircle(rArc);
35015 }
35016
35017 function addBeach(site) {
35018   var x = site[0],
35019       directrix = site[1],
35020       lArc,
35021       rArc,
35022       dxl,
35023       dxr,
35024       node = beaches._;
35025
35026   while (node) {
35027     dxl = leftBreakPoint(node, directrix) - x;
35028     if (dxl > epsilon$4) node = node.L; else {
35029       dxr = x - rightBreakPoint(node, directrix);
35030       if (dxr > epsilon$4) {
35031         if (!node.R) {
35032           lArc = node;
35033           break;
35034         }
35035         node = node.R;
35036       } else {
35037         if (dxl > -epsilon$4) {
35038           lArc = node.P;
35039           rArc = node;
35040         } else if (dxr > -epsilon$4) {
35041           lArc = node;
35042           rArc = node.N;
35043         } else {
35044           lArc = rArc = node;
35045         }
35046         break;
35047       }
35048     }
35049   }
35050
35051   createCell(site);
35052   var newArc = createBeach(site);
35053   beaches.insert(lArc, newArc);
35054
35055   if (!lArc && !rArc) return;
35056
35057   if (lArc === rArc) {
35058     detachCircle(lArc);
35059     rArc = createBeach(lArc.site);
35060     beaches.insert(newArc, rArc);
35061     newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
35062     attachCircle(lArc);
35063     attachCircle(rArc);
35064     return;
35065   }
35066
35067   if (!rArc) { // && lArc
35068     newArc.edge = createEdge(lArc.site, newArc.site);
35069     return;
35070   }
35071
35072   // else lArc !== rArc
35073   detachCircle(lArc);
35074   detachCircle(rArc);
35075
35076   var lSite = lArc.site,
35077       ax = lSite[0],
35078       ay = lSite[1],
35079       bx = site[0] - ax,
35080       by = site[1] - ay,
35081       rSite = rArc.site,
35082       cx = rSite[0] - ax,
35083       cy = rSite[1] - ay,
35084       d = 2 * (bx * cy - by * cx),
35085       hb = bx * bx + by * by,
35086       hc = cx * cx + cy * cy,
35087       vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
35088
35089   setEdgeEnd(rArc.edge, lSite, rSite, vertex);
35090   newArc.edge = createEdge(lSite, site, null, vertex);
35091   rArc.edge = createEdge(site, rSite, null, vertex);
35092   attachCircle(lArc);
35093   attachCircle(rArc);
35094 }
35095
35096 function leftBreakPoint(arc, directrix) {
35097   var site = arc.site,
35098       rfocx = site[0],
35099       rfocy = site[1],
35100       pby2 = rfocy - directrix;
35101
35102   if (!pby2) return rfocx;
35103
35104   var lArc = arc.P;
35105   if (!lArc) return -Infinity;
35106
35107   site = lArc.site;
35108   var lfocx = site[0],
35109       lfocy = site[1],
35110       plby2 = lfocy - directrix;
35111
35112   if (!plby2) return lfocx;
35113
35114   var hl = lfocx - rfocx,
35115       aby2 = 1 / pby2 - 1 / plby2,
35116       b = hl / plby2;
35117
35118   if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
35119
35120   return (rfocx + lfocx) / 2;
35121 }
35122
35123 function rightBreakPoint(arc, directrix) {
35124   var rArc = arc.N;
35125   if (rArc) return leftBreakPoint(rArc, directrix);
35126   var site = arc.site;
35127   return site[1] === directrix ? site[0] : Infinity;
35128 }
35129
35130 var epsilon$4 = 1e-6;
35131 var epsilon2$2 = 1e-12;
35132 var beaches;
35133 var cells;
35134 var circles;
35135 var edges;
35136
35137 function triangleArea(a, b, c) {
35138   return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
35139 }
35140
35141 function lexicographic(a, b) {
35142   return b[1] - a[1]
35143       || b[0] - a[0];
35144 }
35145
35146 function Diagram(sites, extent) {
35147   var site = sites.sort(lexicographic).pop(),
35148       x,
35149       y,
35150       circle;
35151
35152   edges = [];
35153   cells = new Array(sites.length);
35154   beaches = new RedBlackTree;
35155   circles = new RedBlackTree;
35156
35157   while (true) {
35158     circle = firstCircle;
35159     if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
35160       if (site[0] !== x || site[1] !== y) {
35161         addBeach(site);
35162         x = site[0], y = site[1];
35163       }
35164       site = sites.pop();
35165     } else if (circle) {
35166       removeBeach(circle.arc);
35167     } else {
35168       break;
35169     }
35170   }
35171
35172   sortCellHalfedges();
35173
35174   if (extent) {
35175     var x0 = +extent[0][0],
35176         y0 = +extent[0][1],
35177         x1 = +extent[1][0],
35178         y1 = +extent[1][1];
35179     clipEdges(x0, y0, x1, y1);
35180     clipCells(x0, y0, x1, y1);
35181   }
35182
35183   this.edges = edges;
35184   this.cells = cells;
35185
35186   beaches =
35187   circles =
35188   edges =
35189   cells = null;
35190 }
35191
35192 Diagram.prototype = {
35193   constructor: Diagram,
35194
35195   polygons: function() {
35196     var edges = this.edges;
35197
35198     return this.cells.map(function(cell) {
35199       var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
35200       polygon.data = cell.site.data;
35201       return polygon;
35202     });
35203   },
35204
35205   triangles: function() {
35206     var triangles = [],
35207         edges = this.edges;
35208
35209     this.cells.forEach(function(cell, i) {
35210       if (!(m = (halfedges = cell.halfedges).length)) return;
35211       var site = cell.site,
35212           halfedges,
35213           j = -1,
35214           m,
35215           s0,
35216           e1 = edges[halfedges[m - 1]],
35217           s1 = e1.left === site ? e1.right : e1.left;
35218
35219       while (++j < m) {
35220         s0 = s1;
35221         e1 = edges[halfedges[j]];
35222         s1 = e1.left === site ? e1.right : e1.left;
35223         if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
35224           triangles.push([site.data, s0.data, s1.data]);
35225         }
35226       }
35227     });
35228
35229     return triangles;
35230   },
35231
35232   links: function() {
35233     return this.edges.filter(function(edge) {
35234       return edge.right;
35235     }).map(function(edge) {
35236       return {
35237         source: edge.left.data,
35238         target: edge.right.data
35239       };
35240     });
35241   },
35242
35243   find: function(x, y, radius) {
35244     var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;
35245
35246     // Use the previously-found cell, or start with an arbitrary one.
35247     while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
35248     var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;
35249
35250     // Traverse the half-edges to find a closer cell, if any.
35251     do {
35252       cell = that.cells[i0 = i1], i1 = null;
35253       cell.halfedges.forEach(function(e) {
35254         var edge = that.edges[e], v = edge.left;
35255         if ((v === cell.site || !v) && !(v = edge.right)) return;
35256         var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;
35257         if (v2 < d2) d2 = v2, i1 = v.index;
35258       });
35259     } while (i1 !== null);
35260
35261     that._found = i0;
35262
35263     return radius == null || d2 <= radius * radius ? cell.site : null;
35264   }
35265 };
35266
35267 var voronoi = function() {
35268   var x = x$4,
35269       y = y$4,
35270       extent = null;
35271
35272   function voronoi(data) {
35273     return new Diagram(data.map(function(d, i) {
35274       var s = [Math.round(x(d, i, data) / epsilon$4) * epsilon$4, Math.round(y(d, i, data) / epsilon$4) * epsilon$4];
35275       s.index = i;
35276       s.data = d;
35277       return s;
35278     }), extent);
35279   }
35280
35281   voronoi.polygons = function(data) {
35282     return voronoi(data).polygons();
35283   };
35284
35285   voronoi.links = function(data) {
35286     return voronoi(data).links();
35287   };
35288
35289   voronoi.triangles = function(data) {
35290     return voronoi(data).triangles();
35291   };
35292
35293   voronoi.x = function(_) {
35294     return arguments.length ? (x = typeof _ === "function" ? _ : constant$11(+_), voronoi) : x;
35295   };
35296
35297   voronoi.y = function(_) {
35298     return arguments.length ? (y = typeof _ === "function" ? _ : constant$11(+_), voronoi) : y;
35299   };
35300
35301   voronoi.extent = function(_) {
35302     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]]];
35303   };
35304
35305   voronoi.size = function(_) {
35306     return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
35307   };
35308
35309   return voronoi;
35310 };
35311
35312 var constant$12 = function(x) {
35313   return function() {
35314     return x;
35315   };
35316 };
35317
35318 function ZoomEvent(target, type, transform) {
35319   this.target = target;
35320   this.type = type;
35321   this.transform = transform;
35322 }
35323
35324 function Transform(k, x, y) {
35325   this.k = k;
35326   this.x = x;
35327   this.y = y;
35328 }
35329
35330 Transform.prototype = {
35331   constructor: Transform,
35332   scale: function(k) {
35333     return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
35334   },
35335   translate: function(x, y) {
35336     return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
35337   },
35338   apply: function(point) {
35339     return [point[0] * this.k + this.x, point[1] * this.k + this.y];
35340   },
35341   applyX: function(x) {
35342     return x * this.k + this.x;
35343   },
35344   applyY: function(y) {
35345     return y * this.k + this.y;
35346   },
35347   invert: function(location) {
35348     return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
35349   },
35350   invertX: function(x) {
35351     return (x - this.x) / this.k;
35352   },
35353   invertY: function(y) {
35354     return (y - this.y) / this.k;
35355   },
35356   rescaleX: function(x) {
35357     return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
35358   },
35359   rescaleY: function(y) {
35360     return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
35361   },
35362   toString: function() {
35363     return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
35364   }
35365 };
35366
35367 var identity$8 = new Transform(1, 0, 0);
35368
35369 transform$1.prototype = Transform.prototype;
35370
35371 function transform$1(node) {
35372   return node.__zoom || identity$8;
35373 }
35374
35375 function nopropagation$2() {
35376   event.stopImmediatePropagation();
35377 }
35378
35379 var noevent$2 = function() {
35380   event.preventDefault();
35381   event.stopImmediatePropagation();
35382 };
35383
35384 // Ignore right-click, since that should open the context menu.
35385 function defaultFilter$2() {
35386   return !event.button;
35387 }
35388
35389 function defaultExtent$1() {
35390   var e = this, w, h;
35391   if (e instanceof SVGElement) {
35392     e = e.ownerSVGElement || e;
35393     w = e.width.baseVal.value;
35394     h = e.height.baseVal.value;
35395   } else {
35396     w = e.clientWidth;
35397     h = e.clientHeight;
35398   }
35399   return [[0, 0], [w, h]];
35400 }
35401
35402 function defaultTransform() {
35403   return this.__zoom || identity$8;
35404 }
35405
35406 function defaultWheelDelta() {
35407   return -event.deltaY * (event.deltaMode ? 120 : 1) / 500;
35408 }
35409
35410 function touchable$1() {
35411   return "ontouchstart" in this;
35412 }
35413
35414 var zoom = function() {
35415   var filter = defaultFilter$2,
35416       extent = defaultExtent$1,
35417       wheelDelta = defaultWheelDelta,
35418       k0 = 0,
35419       k1 = Infinity,
35420       x0 = -k1,
35421       x1 = k1,
35422       y0 = x0,
35423       y1 = x1,
35424       duration = 250,
35425       interpolate = interpolateZoom,
35426       gestures = [],
35427       listeners = dispatch("start", "zoom", "end"),
35428       touchstarting,
35429       touchending,
35430       touchDelay = 500,
35431       wheelDelay = 150,
35432       clickDistance2 = 0;
35433
35434   function zoom(selection$$1) {
35435     selection$$1
35436         .property("__zoom", defaultTransform)
35437         .on("wheel.zoom", wheeled)
35438         .on("mousedown.zoom", mousedowned)
35439         .on("dblclick.zoom", dblclicked)
35440       .filter(touchable$1)
35441         .on("touchstart.zoom", touchstarted)
35442         .on("touchmove.zoom", touchmoved)
35443         .on("touchend.zoom touchcancel.zoom", touchended)
35444         .style("touch-action", "none")
35445         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
35446   }
35447
35448   zoom.transform = function(collection, transform$$1) {
35449     var selection$$1 = collection.selection ? collection.selection() : collection;
35450     selection$$1.property("__zoom", defaultTransform);
35451     if (collection !== selection$$1) {
35452       schedule(collection, transform$$1);
35453     } else {
35454       selection$$1.interrupt().each(function() {
35455         gesture(this, arguments)
35456             .start()
35457             .zoom(null, typeof transform$$1 === "function" ? transform$$1.apply(this, arguments) : transform$$1)
35458             .end();
35459       });
35460     }
35461   };
35462
35463   zoom.scaleBy = function(selection$$1, k) {
35464     zoom.scaleTo(selection$$1, function() {
35465       var k0 = this.__zoom.k,
35466           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
35467       return k0 * k1;
35468     });
35469   };
35470
35471   zoom.scaleTo = function(selection$$1, k) {
35472     zoom.transform(selection$$1, function() {
35473       var e = extent.apply(this, arguments),
35474           t0 = this.__zoom,
35475           p0 = centroid(e),
35476           p1 = t0.invert(p0),
35477           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
35478       return constrain(translate(scale(t0, k1), p0, p1), e);
35479     });
35480   };
35481
35482   zoom.translateBy = function(selection$$1, x, y) {
35483     zoom.transform(selection$$1, function() {
35484       return constrain(this.__zoom.translate(
35485         typeof x === "function" ? x.apply(this, arguments) : x,
35486         typeof y === "function" ? y.apply(this, arguments) : y
35487       ), extent.apply(this, arguments));
35488     });
35489   };
35490
35491   zoom.translateTo = function(selection$$1, x, y) {
35492     zoom.transform(selection$$1, function() {
35493       var e = extent.apply(this, arguments),
35494           t = this.__zoom,
35495           p = centroid(e);
35496       return constrain(identity$8.translate(p[0], p[1]).scale(t.k).translate(
35497         typeof x === "function" ? -x.apply(this, arguments) : -x,
35498         typeof y === "function" ? -y.apply(this, arguments) : -y
35499       ), e);
35500     });
35501   };
35502
35503   function scale(transform$$1, k) {
35504     k = Math.max(k0, Math.min(k1, k));
35505     return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);
35506   }
35507
35508   function translate(transform$$1, p0, p1) {
35509     var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;
35510     return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);
35511   }
35512
35513   function constrain(transform$$1, extent) {
35514     var dx0 = transform$$1.invertX(extent[0][0]) - x0,
35515         dx1 = transform$$1.invertX(extent[1][0]) - x1,
35516         dy0 = transform$$1.invertY(extent[0][1]) - y0,
35517         dy1 = transform$$1.invertY(extent[1][1]) - y1;
35518     return transform$$1.translate(
35519       dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
35520       dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
35521     );
35522   }
35523
35524   function centroid(extent) {
35525     return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
35526   }
35527
35528   function schedule(transition$$1, transform$$1, center) {
35529     transition$$1
35530         .on("start.zoom", function() { gesture(this, arguments).start(); })
35531         .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
35532         .tween("zoom", function() {
35533           var that = this,
35534               args = arguments,
35535               g = gesture(that, args),
35536               e = extent.apply(that, args),
35537               p = center || centroid(e),
35538               w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
35539               a = that.__zoom,
35540               b = typeof transform$$1 === "function" ? transform$$1.apply(that, args) : transform$$1,
35541               i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
35542           return function(t) {
35543             if (t === 1) t = b; // Avoid rounding error on end.
35544             else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
35545             g.zoom(null, t);
35546           };
35547         });
35548   }
35549
35550   function gesture(that, args) {
35551     for (var i = 0, n = gestures.length, g; i < n; ++i) {
35552       if ((g = gestures[i]).that === that) {
35553         return g;
35554       }
35555     }
35556     return new Gesture(that, args);
35557   }
35558
35559   function Gesture(that, args) {
35560     this.that = that;
35561     this.args = args;
35562     this.index = -1;
35563     this.active = 0;
35564     this.extent = extent.apply(that, args);
35565   }
35566
35567   Gesture.prototype = {
35568     start: function() {
35569       if (++this.active === 1) {
35570         this.index = gestures.push(this) - 1;
35571         this.emit("start");
35572       }
35573       return this;
35574     },
35575     zoom: function(key, transform$$1) {
35576       if (this.mouse && key !== "mouse") this.mouse[1] = transform$$1.invert(this.mouse[0]);
35577       if (this.touch0 && key !== "touch") this.touch0[1] = transform$$1.invert(this.touch0[0]);
35578       if (this.touch1 && key !== "touch") this.touch1[1] = transform$$1.invert(this.touch1[0]);
35579       this.that.__zoom = transform$$1;
35580       this.emit("zoom");
35581       return this;
35582     },
35583     end: function() {
35584       if (--this.active === 0) {
35585         gestures.splice(this.index, 1);
35586         this.index = -1;
35587         this.emit("end");
35588       }
35589       return this;
35590     },
35591     emit: function(type) {
35592       customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
35593     }
35594   };
35595
35596   function wheeled() {
35597     if (!filter.apply(this, arguments)) return;
35598     var g = gesture(this, arguments),
35599         t = this.__zoom,
35600         k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
35601         p = mouse(this);
35602
35603     // If the mouse is in the same location as before, reuse it.
35604     // If there were recent wheel events, reset the wheel idle timeout.
35605     if (g.wheel) {
35606       if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
35607         g.mouse[1] = t.invert(g.mouse[0] = p);
35608       }
35609       clearTimeout(g.wheel);
35610     }
35611
35612     // If this wheel event won’t trigger a transform change, ignore it.
35613     else if (t.k === k) return;
35614
35615     // Otherwise, capture the mouse point and location at the start.
35616     else {
35617       g.mouse = [p, t.invert(p)];
35618       interrupt(this);
35619       g.start();
35620     }
35621
35622     noevent$2();
35623     g.wheel = setTimeout(wheelidled, wheelDelay);
35624     g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));
35625
35626     function wheelidled() {
35627       g.wheel = null;
35628       g.end();
35629     }
35630   }
35631
35632   function mousedowned() {
35633     if (touchending || !filter.apply(this, arguments)) return;
35634     var g = gesture(this, arguments),
35635         v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
35636         p = mouse(this),
35637         x0 = event.clientX,
35638         y0 = event.clientY;
35639
35640     dragDisable(event.view);
35641     nopropagation$2();
35642     g.mouse = [p, this.__zoom.invert(p)];
35643     interrupt(this);
35644     g.start();
35645
35646     function mousemoved() {
35647       noevent$2();
35648       if (!g.moved) {
35649         var dx = event.clientX - x0, dy = event.clientY - y0;
35650         g.moved = dx * dx + dy * dy > clickDistance2;
35651       }
35652       g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent));
35653     }
35654
35655     function mouseupped() {
35656       v.on("mousemove.zoom mouseup.zoom", null);
35657       yesdrag(event.view, g.moved);
35658       noevent$2();
35659       g.end();
35660     }
35661   }
35662
35663   function dblclicked() {
35664     if (!filter.apply(this, arguments)) return;
35665     var t0 = this.__zoom,
35666         p0 = mouse(this),
35667         p1 = t0.invert(p0),
35668         k1 = t0.k * (event.shiftKey ? 0.5 : 2),
35669         t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));
35670
35671     noevent$2();
35672     if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);
35673     else select(this).call(zoom.transform, t1);
35674   }
35675
35676   function touchstarted() {
35677     if (!filter.apply(this, arguments)) return;
35678     var g = gesture(this, arguments),
35679         touches$$1 = event.changedTouches,
35680         started,
35681         n = touches$$1.length, i, t, p;
35682
35683     nopropagation$2();
35684     for (i = 0; i < n; ++i) {
35685       t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
35686       p = [p, this.__zoom.invert(p), t.identifier];
35687       if (!g.touch0) g.touch0 = p, started = true;
35688       else if (!g.touch1) g.touch1 = p;
35689     }
35690
35691     // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
35692     if (touchstarting) {
35693       touchstarting = clearTimeout(touchstarting);
35694       if (!g.touch1) {
35695         g.end();
35696         p = select(this).on("dblclick.zoom");
35697         if (p) p.apply(this, arguments);
35698         return;
35699       }
35700     }
35701
35702     if (started) {
35703       touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
35704       interrupt(this);
35705       g.start();
35706     }
35707   }
35708
35709   function touchmoved() {
35710     var g = gesture(this, arguments),
35711         touches$$1 = event.changedTouches,
35712         n = touches$$1.length, i, t, p, l;
35713
35714     noevent$2();
35715     if (touchstarting) touchstarting = clearTimeout(touchstarting);
35716     for (i = 0; i < n; ++i) {
35717       t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
35718       if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
35719       else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
35720     }
35721     t = g.that.__zoom;
35722     if (g.touch1) {
35723       var p0 = g.touch0[0], l0 = g.touch0[1],
35724           p1 = g.touch1[0], l1 = g.touch1[1],
35725           dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
35726           dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
35727       t = scale(t, Math.sqrt(dp / dl));
35728       p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
35729       l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
35730     }
35731     else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
35732     else return;
35733     g.zoom("touch", constrain(translate(t, p, l), g.extent));
35734   }
35735
35736   function touchended() {
35737     var g = gesture(this, arguments),
35738         touches$$1 = event.changedTouches,
35739         n = touches$$1.length, i, t;
35740
35741     nopropagation$2();
35742     if (touchending) clearTimeout(touchending);
35743     touchending = setTimeout(function() { touchending = null; }, touchDelay);
35744     for (i = 0; i < n; ++i) {
35745       t = touches$$1[i];
35746       if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
35747       else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
35748     }
35749     if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
35750     if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);
35751     else g.end();
35752   }
35753
35754   zoom.wheelDelta = function(_) {
35755     return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$12(+_), zoom) : wheelDelta;
35756   };
35757
35758   zoom.filter = function(_) {
35759     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter;
35760   };
35761
35762   zoom.extent = function(_) {
35763     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
35764   };
35765
35766   zoom.scaleExtent = function(_) {
35767     return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];
35768   };
35769
35770   zoom.translateExtent = function(_) {
35771     return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];
35772   };
35773
35774   zoom.duration = function(_) {
35775     return arguments.length ? (duration = +_, zoom) : duration;
35776   };
35777
35778   zoom.interpolate = function(_) {
35779     return arguments.length ? (interpolate = _, zoom) : interpolate;
35780   };
35781
35782   zoom.on = function() {
35783     var value = listeners.on.apply(listeners, arguments);
35784     return value === listeners ? zoom : value;
35785   };
35786
35787   zoom.clickDistance = function(_) {
35788     return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);
35789   };
35790
35791   return zoom;
35792 };
35793
35794
35795
35796 var index$2 = Object.freeze({
35797         version: version,
35798         bisect: bisectRight,
35799         bisectRight: bisectRight,
35800         bisectLeft: bisectLeft,
35801         ascending: ascending,
35802         bisector: bisector,
35803         cross: cross,
35804         descending: descending,
35805         deviation: deviation,
35806         extent: extent,
35807         histogram: histogram,
35808         thresholdFreedmanDiaconis: freedmanDiaconis,
35809         thresholdScott: scott,
35810         thresholdSturges: sturges,
35811         max: max,
35812         mean: mean,
35813         median: median,
35814         merge: merge,
35815         min: min,
35816         pairs: pairs,
35817         permute: permute,
35818         quantile: threshold,
35819         range: sequence,
35820         scan: scan,
35821         shuffle: shuffle,
35822         sum: sum,
35823         ticks: ticks,
35824         tickIncrement: tickIncrement,
35825         tickStep: tickStep,
35826         transpose: transpose,
35827         variance: variance,
35828         zip: zip,
35829         axisTop: axisTop,
35830         axisRight: axisRight,
35831         axisBottom: axisBottom,
35832         axisLeft: axisLeft,
35833         brush: brush,
35834         brushX: brushX,
35835         brushY: brushY,
35836         brushSelection: brushSelection,
35837         chord: chord,
35838         ribbon: ribbon,
35839         nest: nest,
35840         set: set$2,
35841         map: map$1,
35842         keys: keys,
35843         values: values,
35844         entries: entries,
35845         color: color,
35846         rgb: rgb,
35847         hsl: hsl,
35848         lab: lab,
35849         hcl: hcl,
35850         cubehelix: cubehelix,
35851         dispatch: dispatch,
35852         drag: drag,
35853         dragDisable: dragDisable,
35854         dragEnable: yesdrag,
35855         dsvFormat: dsv,
35856         csvParse: csvParse,
35857         csvParseRows: csvParseRows,
35858         csvFormat: csvFormat,
35859         csvFormatRows: csvFormatRows,
35860         tsvParse: tsvParse,
35861         tsvParseRows: tsvParseRows,
35862         tsvFormat: tsvFormat,
35863         tsvFormatRows: tsvFormatRows,
35864         easeLinear: linear$1,
35865         easeQuad: quadInOut,
35866         easeQuadIn: quadIn,
35867         easeQuadOut: quadOut,
35868         easeQuadInOut: quadInOut,
35869         easeCubic: cubicInOut,
35870         easeCubicIn: cubicIn,
35871         easeCubicOut: cubicOut,
35872         easeCubicInOut: cubicInOut,
35873         easePoly: polyInOut,
35874         easePolyIn: polyIn,
35875         easePolyOut: polyOut,
35876         easePolyInOut: polyInOut,
35877         easeSin: sinInOut,
35878         easeSinIn: sinIn,
35879         easeSinOut: sinOut,
35880         easeSinInOut: sinInOut,
35881         easeExp: expInOut,
35882         easeExpIn: expIn,
35883         easeExpOut: expOut,
35884         easeExpInOut: expInOut,
35885         easeCircle: circleInOut,
35886         easeCircleIn: circleIn,
35887         easeCircleOut: circleOut,
35888         easeCircleInOut: circleInOut,
35889         easeBounce: bounceOut,
35890         easeBounceIn: bounceIn,
35891         easeBounceOut: bounceOut,
35892         easeBounceInOut: bounceInOut,
35893         easeBack: backInOut,
35894         easeBackIn: backIn,
35895         easeBackOut: backOut,
35896         easeBackInOut: backInOut,
35897         easeElastic: elasticOut,
35898         easeElasticIn: elasticIn,
35899         easeElasticOut: elasticOut,
35900         easeElasticInOut: elasticInOut,
35901         forceCenter: center$1,
35902         forceCollide: collide,
35903         forceLink: link,
35904         forceManyBody: manyBody,
35905         forceSimulation: simulation,
35906         forceX: x$2,
35907         forceY: y$2,
35908         formatDefaultLocale: defaultLocale,
35909         get format () { return format; },
35910         get formatPrefix () { return formatPrefix; },
35911         formatLocale: formatLocale,
35912         formatSpecifier: formatSpecifier,
35913         precisionFixed: precisionFixed,
35914         precisionPrefix: precisionPrefix,
35915         precisionRound: precisionRound,
35916         geoArea: area,
35917         geoBounds: bounds,
35918         geoCentroid: d3GeoCentroid,
35919         geoCircle: circle,
35920         geoClipExtent: extent$1,
35921         geoContains: contains,
35922         geoDistance: distance,
35923         geoGraticule: graticule,
35924         geoGraticule10: graticule10,
35925         geoInterpolate: interpolate$1,
35926         geoLength: d3GeoLength,
35927         geoPath: index$4,
35928         geoAlbers: albers,
35929         geoAlbersUsa: albersUsa,
35930         geoAzimuthalEqualArea: azimuthalEqualArea,
35931         geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
35932         geoAzimuthalEquidistant: azimuthalEquidistant,
35933         geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
35934         geoConicConformal: conicConformal,
35935         geoConicConformalRaw: conicConformalRaw,
35936         geoConicEqualArea: conicEqualArea,
35937         geoConicEqualAreaRaw: conicEqualAreaRaw,
35938         geoConicEquidistant: conicEquidistant,
35939         geoConicEquidistantRaw: conicEquidistantRaw,
35940         geoEquirectangular: equirectangular,
35941         geoEquirectangularRaw: equirectangularRaw,
35942         geoGnomonic: gnomonic,
35943         geoGnomonicRaw: gnomonicRaw,
35944         geoIdentity: identity$5,
35945         geoProjection: projection,
35946         geoProjectionMutator: projectionMutator,
35947         geoMercator: mercator,
35948         geoMercatorRaw: mercatorRaw,
35949         geoOrthographic: orthographic,
35950         geoOrthographicRaw: orthographicRaw,
35951         geoStereographic: stereographic,
35952         geoStereographicRaw: stereographicRaw,
35953         geoTransverseMercator: transverseMercator,
35954         geoTransverseMercatorRaw: transverseMercatorRaw,
35955         geoRotation: rotation,
35956         geoStream: geoStream,
35957         geoTransform: transform,
35958         cluster: cluster,
35959         hierarchy: hierarchy,
35960         pack: index$5,
35961         packSiblings: siblings,
35962         packEnclose: enclose,
35963         partition: partition,
35964         stratify: stratify,
35965         tree: tree,
35966         treemap: index$6,
35967         treemapBinary: binary,
35968         treemapDice: treemapDice,
35969         treemapSlice: treemapSlice,
35970         treemapSliceDice: sliceDice,
35971         treemapSquarify: squarify,
35972         treemapResquarify: resquarify,
35973         interpolate: interpolateValue,
35974         interpolateArray: array$1,
35975         interpolateBasis: basis$1,
35976         interpolateBasisClosed: basisClosed,
35977         interpolateDate: date,
35978         interpolateNumber: reinterpolate,
35979         interpolateObject: object,
35980         interpolateRound: interpolateRound,
35981         interpolateString: interpolateString,
35982         interpolateTransformCss: interpolateTransformCss,
35983         interpolateTransformSvg: interpolateTransformSvg,
35984         interpolateZoom: interpolateZoom,
35985         interpolateRgb: interpolateRgb,
35986         interpolateRgbBasis: rgbBasis,
35987         interpolateRgbBasisClosed: rgbBasisClosed,
35988         interpolateHsl: hsl$2,
35989         interpolateHslLong: hslLong,
35990         interpolateLab: lab$1,
35991         interpolateHcl: hcl$2,
35992         interpolateHclLong: hclLong,
35993         interpolateCubehelix: cubehelix$2,
35994         interpolateCubehelixLong: cubehelixLong,
35995         quantize: quantize,
35996         path: path,
35997         polygonArea: d3polygonArea,
35998         polygonCentroid: d3polygonCentroid,
35999         polygonHull: d3polygonHull,
36000         polygonContains: contains$1,
36001         polygonLength: length$1,
36002         quadtree: quadtree,
36003         queue: queue,
36004         randomUniform: uniform,
36005         randomNormal: normal,
36006         randomLogNormal: logNormal,
36007         randomBates: bates,
36008         randomIrwinHall: irwinHall,
36009         randomExponential: exponential$1,
36010         request: request,
36011         html: html,
36012         json: json,
36013         text: text,
36014         xml: xml,
36015         csv: csv$1,
36016         tsv: tsv$1,
36017         scaleBand: band,
36018         scalePoint: point$1,
36019         scaleIdentity: identity$6,
36020         scaleLinear: linear$2,
36021         scaleLog: log$1,
36022         scaleOrdinal: ordinal,
36023         scaleImplicit: implicit,
36024         scalePow: pow$1,
36025         scaleSqrt: sqrt$1,
36026         scaleQuantile: quantile,
36027         scaleQuantize: quantize$1,
36028         scaleThreshold: threshold$1,
36029         scaleTime: time,
36030         scaleUtc: utcTime,
36031         schemeCategory10: category10,
36032         schemeCategory20b: category20b,
36033         schemeCategory20c: category20c,
36034         schemeCategory20: category20,
36035         interpolateCubehelixDefault: cubehelix$3,
36036         interpolateRainbow: rainbow$1,
36037         interpolateWarm: warm,
36038         interpolateCool: cool,
36039         interpolateViridis: viridis,
36040         interpolateMagma: magma,
36041         interpolateInferno: inferno,
36042         interpolatePlasma: plasma,
36043         scaleSequential: sequential,
36044         creator: creator,
36045         local: local$1,
36046         matcher: matcher$1,
36047         mouse: mouse,
36048         namespace: namespace,
36049         namespaces: namespaces,
36050         select: select,
36051         selectAll: selectAll,
36052         selection: selection,
36053         selector: selector,
36054         selectorAll: selectorAll,
36055         style: styleValue,
36056         touch: touch,
36057         touches: touches,
36058         window: defaultView,
36059         get event () { return event; },
36060         customEvent: customEvent,
36061         arc: arc,
36062         area: area$1,
36063         line: line,
36064         pie: pie,
36065         areaRadial: areaRadial,
36066         radialArea: areaRadial,
36067         lineRadial: lineRadial$1,
36068         radialLine: lineRadial$1,
36069         pointRadial: pointRadial,
36070         linkHorizontal: linkHorizontal,
36071         linkVertical: linkVertical,
36072         linkRadial: linkRadial,
36073         symbol: symbol,
36074         symbols: symbols,
36075         symbolCircle: circle$2,
36076         symbolCross: cross$2,
36077         symbolDiamond: diamond,
36078         symbolSquare: square,
36079         symbolStar: star,
36080         symbolTriangle: triangle,
36081         symbolWye: wye,
36082         curveBasisClosed: basisClosed$1,
36083         curveBasisOpen: basisOpen,
36084         curveBasis: basis$2,
36085         curveBundle: bundle,
36086         curveCardinalClosed: cardinalClosed,
36087         curveCardinalOpen: cardinalOpen,
36088         curveCardinal: cardinal,
36089         curveCatmullRomClosed: catmullRomClosed,
36090         curveCatmullRomOpen: catmullRomOpen,
36091         curveCatmullRom: catmullRom,
36092         curveLinearClosed: linearClosed,
36093         curveLinear: curveLinear,
36094         curveMonotoneX: monotoneX,
36095         curveMonotoneY: monotoneY,
36096         curveNatural: natural,
36097         curveStep: step,
36098         curveStepAfter: stepAfter,
36099         curveStepBefore: stepBefore,
36100         stack: stack,
36101         stackOffsetExpand: expand,
36102         stackOffsetDiverging: diverging,
36103         stackOffsetNone: none$1,
36104         stackOffsetSilhouette: silhouette,
36105         stackOffsetWiggle: wiggle,
36106         stackOrderAscending: ascending$2,
36107         stackOrderDescending: descending$2,
36108         stackOrderInsideOut: insideOut,
36109         stackOrderNone: none$2,
36110         stackOrderReverse: reverse,
36111         timeInterval: newInterval,
36112         timeMillisecond: millisecond,
36113         timeMilliseconds: milliseconds,
36114         utcMillisecond: millisecond,
36115         utcMilliseconds: milliseconds,
36116         timeSecond: second,
36117         timeSeconds: seconds,
36118         utcSecond: second,
36119         utcSeconds: seconds,
36120         timeMinute: minute,
36121         timeMinutes: minutes,
36122         timeHour: hour,
36123         timeHours: hours,
36124         timeDay: day,
36125         timeDays: days,
36126         timeWeek: sunday,
36127         timeWeeks: sundays,
36128         timeSunday: sunday,
36129         timeSundays: sundays,
36130         timeMonday: monday,
36131         timeMondays: mondays,
36132         timeTuesday: tuesday,
36133         timeTuesdays: tuesdays,
36134         timeWednesday: wednesday,
36135         timeWednesdays: wednesdays,
36136         timeThursday: thursday,
36137         timeThursdays: thursdays,
36138         timeFriday: friday,
36139         timeFridays: fridays,
36140         timeSaturday: saturday,
36141         timeSaturdays: saturdays,
36142         timeMonth: month,
36143         timeMonths: months,
36144         timeYear: year,
36145         timeYears: years,
36146         utcMinute: utcMinute,
36147         utcMinutes: utcMinutes,
36148         utcHour: utcHour,
36149         utcHours: utcHours,
36150         utcDay: utcDay,
36151         utcDays: utcDays,
36152         utcWeek: utcSunday,
36153         utcWeeks: utcSundays,
36154         utcSunday: utcSunday,
36155         utcSundays: utcSundays,
36156         utcMonday: utcMonday,
36157         utcMondays: utcMondays,
36158         utcTuesday: utcTuesday,
36159         utcTuesdays: utcTuesdays,
36160         utcWednesday: utcWednesday,
36161         utcWednesdays: utcWednesdays,
36162         utcThursday: utcThursday,
36163         utcThursdays: utcThursdays,
36164         utcFriday: utcFriday,
36165         utcFridays: utcFridays,
36166         utcSaturday: utcSaturday,
36167         utcSaturdays: utcSaturdays,
36168         utcMonth: utcMonth,
36169         utcMonths: utcMonths,
36170         utcYear: utcYear,
36171         utcYears: utcYears,
36172         timeFormatDefaultLocale: defaultLocale$1,
36173         get timeFormat () { return timeFormat; },
36174         get timeParse () { return timeParse; },
36175         get utcFormat () { return utcFormat; },
36176         get utcParse () { return utcParse; },
36177         timeFormatLocale: formatLocale$1,
36178         isoFormat: formatIso,
36179         isoParse: parseIso,
36180         now: now,
36181         timer: timer,
36182         timerFlush: timerFlush,
36183         timeout: timeout$1,
36184         interval: interval$1,
36185         transition: transition,
36186         active: active,
36187         interrupt: interrupt,
36188         voronoi: voronoi,
36189         zoom: zoom,
36190         zoomTransform: transform$1,
36191         zoomIdentity: identity$8
36192 });
36193
36194 /*
36195     Bypasses features of D3's default projection stream pipeline that are unnecessary:
36196     * Antimeridian clipping
36197     * Spherical rotation
36198     * Resampling
36199 */
36200 function geoRawMercator() {
36201     var project = mercatorRaw,
36202         k = 512 / Math.PI, // scale
36203         x = 0, y = 0, // translate
36204         clipExtent = [[0, 0], [0, 0]];
36205
36206
36207     function projection$$1(point) {
36208         point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
36209         return [point[0] * k + x, y - point[1] * k];
36210     }
36211
36212
36213     projection$$1.invert = function(point) {
36214         point = project.invert((point[0] - x) / k, (y - point[1]) / k);
36215         return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
36216     };
36217
36218
36219     projection$$1.scale = function(_) {
36220         if (!arguments.length) return k;
36221         k = +_;
36222         return projection$$1;
36223     };
36224
36225
36226     projection$$1.translate = function(_) {
36227         if (!arguments.length) return [x, y];
36228         x = +_[0];
36229         y = +_[1];
36230         return projection$$1;
36231     };
36232
36233
36234     projection$$1.clipExtent = function(_) {
36235         if (!arguments.length) return clipExtent;
36236         clipExtent = _;
36237         return projection$$1;
36238     };
36239
36240
36241     projection$$1.transform = function(_) {
36242         if (!arguments.length) return identity$8.translate(x, y).scale(k);
36243         x = +_.x;
36244         y = +_.y;
36245         k = +_.k;
36246         return projection$$1;
36247     };
36248
36249
36250     projection$$1.stream = transform({
36251         point: function(x, y) {
36252             x = projection$$1([x, y]);
36253             this.stream.point(x[0], x[1]);
36254         }
36255     }).stream;
36256
36257
36258     return projection$$1;
36259 }
36260
36261 function osmChangeset() {
36262     if (!(this instanceof osmChangeset)) {
36263         return (new osmChangeset()).initialize(arguments);
36264     } else if (arguments.length) {
36265         this.initialize(arguments);
36266     }
36267 }
36268
36269
36270 osmEntity$$1.changeset = osmChangeset;
36271
36272 osmChangeset.prototype = Object.create(osmEntity$$1.prototype);
36273
36274 lodash.extend(osmChangeset.prototype, {
36275
36276     type: 'changeset',
36277
36278
36279     extent: function() {
36280         return new geoExtent$$1();
36281     },
36282
36283
36284     geometry: function() {
36285         return 'changeset';
36286     },
36287
36288
36289     asJXON: function() {
36290         return {
36291             osm: {
36292                 changeset: {
36293                     tag: lodash.map(this.tags, function(value, key) {
36294                         return { '@k': key, '@v': value };
36295                     }),
36296                     '@version': 0.6,
36297                     '@generator': 'iD'
36298                 }
36299             }
36300         };
36301     },
36302
36303
36304     // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
36305     // XML. Returns a string.
36306     osmChangeJXON: function(changes) {
36307         var changeset_id = this.id;
36308
36309         function nest(x, order) {
36310             var groups = {};
36311             for (var i = 0; i < x.length; i++) {
36312                 var tagName = Object.keys(x[i])[0];
36313                 if (!groups[tagName]) groups[tagName] = [];
36314                 groups[tagName].push(x[i][tagName]);
36315             }
36316             var ordered = {};
36317             order.forEach(function(o) {
36318                 if (groups[o]) ordered[o] = groups[o];
36319             });
36320             return ordered;
36321         }
36322
36323
36324         // sort relations in a changeset by dependencies
36325         function sort(changes) {
36326
36327             // find a referenced relation in the current changeset
36328             function resolve(item) {
36329                 return lodash.find(relations, function(relation) {
36330                     return item.keyAttributes.type === 'relation'
36331                         && item.keyAttributes.ref === relation['@id'];
36332                 });
36333             }
36334
36335             // a new item is an item that has not been already processed
36336             function isNew(item) {
36337                 return !sorted[ item['@id'] ] && !lodash.find(processing, function(proc) {
36338                     return proc['@id'] === item['@id'];
36339                 });
36340             }
36341
36342             var processing = [],
36343                 sorted = {},
36344                 relations = changes.relation;
36345
36346             if (!relations) return changes;
36347
36348             for (var i = 0; i < relations.length; i++) {
36349                 var relation = relations[i];
36350
36351                 // skip relation if already sorted
36352                 if (!sorted[relation['@id']]) {
36353                     processing.push(relation);
36354                 }
36355
36356                 while (processing.length > 0) {
36357                     var next = processing[0],
36358                     deps = lodash.filter(lodash.compact(next.member.map(resolve)), isNew);
36359                     if (deps.length === 0) {
36360                         sorted[next['@id']] = next;
36361                         processing.shift();
36362                     } else {
36363                         processing = deps.concat(processing);
36364                     }
36365                 }
36366             }
36367
36368             changes.relation = lodash.values(sorted);
36369             return changes;
36370         }
36371
36372         function rep(entity) {
36373             return entity.asJXON(changeset_id);
36374         }
36375
36376         return {
36377             osmChange: {
36378                 '@version': 0.6,
36379                 '@generator': 'iD',
36380                 'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])),
36381                 'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']),
36382                 'delete': lodash.extend(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), { '@if-unused': true })
36383             }
36384         };
36385     },
36386
36387
36388     asGeoJSON: function() {
36389         return {};
36390     }
36391
36392 });
36393
36394 function osmNode() {
36395     if (!(this instanceof osmNode)) {
36396         return (new osmNode()).initialize(arguments);
36397     } else if (arguments.length) {
36398         this.initialize(arguments);
36399     }
36400 }
36401
36402 osmEntity$$1.node = osmNode;
36403
36404 osmNode.prototype = Object.create(osmEntity$$1.prototype);
36405
36406 lodash.extend(osmNode.prototype, {
36407
36408     type: 'node',
36409
36410
36411     extent: function() {
36412         return new geoExtent$$1(this.loc);
36413     },
36414
36415
36416     geometry: function(graph) {
36417         return graph.transient(this, 'geometry', function() {
36418             return graph.isPoi(this) ? 'point' : 'vertex';
36419         });
36420     },
36421
36422
36423     move: function(loc) {
36424         return this.update({loc: loc});
36425     },
36426
36427
36428     isDegenerate: function() {
36429         return !(
36430             Array.isArray(this.loc) && this.loc.length === 2 &&
36431             this.loc[0] >= -180 && this.loc[0] <= 180 &&
36432             this.loc[1] >= -90 && this.loc[1] <= 90
36433         );
36434     },
36435
36436
36437     isEndpoint: function(resolver) {
36438         return resolver.transient(this, 'isEndpoint', function() {
36439             var id = this.id;
36440             return resolver.parentWays(this).filter(function(parent) {
36441                 return !parent.isClosed() && !!parent.affix(id);
36442             }).length > 0;
36443         });
36444     },
36445
36446
36447     isConnected: function(resolver) {
36448         return resolver.transient(this, 'isConnected', function() {
36449             var parents = resolver.parentWays(this);
36450
36451             function isLine(entity) {
36452                 return entity.geometry(resolver) === 'line' &&
36453                     entity.hasInterestingTags();
36454             }
36455
36456             // vertex is connected to multiple parent lines
36457             if (parents.length > 1 && lodash.some(parents, isLine)) {
36458                 return true;
36459
36460             } else if (parents.length === 1) {
36461                 var way = parents[0],
36462                     nodes = way.nodes.slice();
36463                 if (way.isClosed()) { nodes.pop(); }  // ignore connecting node if closed
36464
36465                 // return true if vertex appears multiple times (way is self intersecting)
36466                 return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id);
36467             }
36468
36469             return false;
36470         });
36471     },
36472
36473
36474     isIntersection: function(resolver) {
36475         return resolver.transient(this, 'isIntersection', function() {
36476             return resolver.parentWays(this).filter(function(parent) {
36477                 return (parent.tags.highway ||
36478                     parent.tags.waterway ||
36479                     parent.tags.railway ||
36480                     parent.tags.aeroway) &&
36481                     parent.geometry(resolver) === 'line';
36482             }).length > 1;
36483         });
36484     },
36485
36486
36487     isHighwayIntersection: function(resolver) {
36488         return resolver.transient(this, 'isHighwayIntersection', function() {
36489             return resolver.parentWays(this).filter(function(parent) {
36490                 return parent.tags.highway && parent.geometry(resolver) === 'line';
36491             }).length > 1;
36492         });
36493     },
36494
36495
36496     isOnAddressLine: function(resolver) {
36497         return resolver.transient(this, 'isOnAddressLine', function() {
36498             return resolver.parentWays(this).filter(function(parent) {
36499                 return parent.tags.hasOwnProperty('addr:interpolation') &&
36500                     parent.geometry(resolver) === 'line';
36501             }).length > 0;
36502         });
36503     },
36504
36505
36506     asJXON: function(changeset_id) {
36507         var r = {
36508             node: {
36509                 '@id': this.osmId(),
36510                 '@lon': this.loc[0],
36511                 '@lat': this.loc[1],
36512                 '@version': (this.version || 0),
36513                 tag: lodash.map(this.tags, function(v, k) {
36514                     return { keyAttributes: { k: k, v: v } };
36515                 })
36516             }
36517         };
36518         if (changeset_id) r.node['@changeset'] = changeset_id;
36519         return r;
36520     },
36521
36522
36523     asGeoJSON: function() {
36524         return {
36525             type: 'Point',
36526             coordinates: this.loc
36527         };
36528     }
36529 });
36530
36531 /*
36532   Order the nodes of a way in reverse order and reverse any direction dependent tags
36533   other than `oneway`. (We assume that correcting a backwards oneway is the primary
36534   reason for reversing a way.)
36535
36536   The following transforms are performed:
36537
36538     Keys:
36539           *:right=* ⟺ *:left=*
36540         *:forward=* ⟺ *:backward=*
36541        direction=up ⟺ direction=down
36542          incline=up ⟺ incline=down
36543             *=right ⟺ *=left
36544
36545     Relation members:
36546        role=forward ⟺ role=backward
36547          role=north ⟺ role=south
36548           role=east ⟺ role=west
36549
36550    In addition, numeric-valued `incline` tags are negated.
36551
36552    The JOSM implementation was used as a guide, but transformations that were of unclear benefit
36553    or adjusted tags that don't seem to be used in practice were omitted.
36554
36555    Also, each node on the way is examined for its own tags and the following transformations are performed
36556    in order to ensure associated nodes (eg a Stop Sign) is also reversed
36557
36558     Node Keys:
36559         direction=forward ⟺ direction=backward
36560         direction=left ⟺ direction=right
36561         *:forward=* ⟺ *:backward=*
36562         *:left=* ⟺ *:right=*
36563
36564    References:
36565       http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
36566       http://wiki.openstreetmap.org/wiki/Key:direction#Steps
36567       http://wiki.openstreetmap.org/wiki/Key:incline
36568       http://wiki.openstreetmap.org/wiki/Route#Members
36569       http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
36570       http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
36571       http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
36572  */
36573 function actionReverse(wayId, options) {
36574     var replacements = [
36575             [/:right$/, ':left'], [/:left$/, ':right'],
36576             [/:forward$/, ':backward'], [/:backward$/, ':forward']
36577         ],
36578         numeric = /^([+\-]?)(?=[\d.])/,
36579         roleReversals = {
36580             forward: 'backward',
36581             backward: 'forward',
36582             north: 'south',
36583             south: 'north',
36584             east: 'west',
36585             west: 'east'
36586         };
36587
36588
36589     function reverseKey(key) {
36590         for (var i = 0; i < replacements.length; ++i) {
36591             var replacement = replacements[i];
36592             if (replacement[0].test(key)) {
36593                 return key.replace(replacement[0], replacement[1]);
36594             }
36595         }
36596         return key;
36597     }
36598
36599
36600     function reverseValue(key, value) {
36601         if (key === 'incline' && numeric.test(value)) {
36602             return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
36603         } else if (key === 'incline' || key === 'direction') {
36604             return {up: 'down', down: 'up'}[value] || value;
36605         } else if (options && options.reverseOneway && key === 'oneway') {
36606             return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
36607         } else {
36608             return {left: 'right', right: 'left'}[value] || value;
36609         }
36610     }
36611
36612
36613     function reverseDirectionTags(node) {
36614         // Update the direction based tags as appropriate then return an updated node
36615         return node.update({tags: lodash.transform(node.tags, function(acc, tagValue, tagKey) {
36616             // See if this is a direction tag and reverse (or use existing value if not recognised)
36617             if (tagKey === 'direction') {
36618                 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
36619             } else {
36620                 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
36621                 // This will pass through other tags unchanged
36622                 acc[reverseKey(tagKey)] = tagValue;
36623             }
36624             return acc;
36625         }, {})});
36626     }
36627
36628
36629     function reverseTagsOnNodes(graph, nodeIds) {
36630         // Reverse the direction of appropriate tags attached to the nodes (#3076)
36631         return lodash(nodeIds)
36632             // Get each node from the graph
36633             .map(function(nodeId) { return graph.entity(nodeId);})
36634             // Check tags on the node, if there aren't any, we can skip
36635             .filter(function(existingNode) { return existingNode.tags !== undefined;})
36636             // Get a new version of each node with the appropriate tags reversed
36637             .map(function(existingNode) { return reverseDirectionTags(existingNode);})
36638             // Chain together consecutive updates to the graph for each updated node and return
36639             .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
36640     }
36641
36642
36643     return function(graph) {
36644         var way = graph.entity(wayId),
36645             nodes = way.nodes.slice().reverse(),
36646             tags = {}, key, role;
36647
36648         for (key in way.tags) {
36649             tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
36650         }
36651
36652         graph.parentRelations(way).forEach(function(relation) {
36653             relation.members.forEach(function(member, index) {
36654                 if (member.id === way.id && (role = roleReversals[member.role])) {
36655                     relation = relation.updateMember({role: role}, index);
36656                     graph = graph.replace(relation);
36657                 }
36658             });
36659         });
36660
36661         // Reverse any associated directions on nodes on the way and then replace
36662         // the way itself with the reversed node ids and updated way tags
36663         return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
36664     };
36665 }
36666
36667 // For fixing up rendering of multipolygons with tags on the outer member.
36668 // https://github.com/openstreetmap/iD/issues/613
36669 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
36670     if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0)
36671         return false;
36672
36673     var parents = graph.parentRelations(entity);
36674     if (parents.length !== 1)
36675         return false;
36676
36677     var parent = parents[0];
36678     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
36679         return false;
36680
36681     var members = parent.members, member;
36682     for (var i = 0; i < members.length; i++) {
36683         member = members[i];
36684         if (member.id === entity.id && member.role && member.role !== 'outer')
36685             return false; // Not outer member
36686         if (member.id !== entity.id && (!member.role || member.role === 'outer'))
36687             return false; // Not a simple multipolygon
36688     }
36689
36690     return parent;
36691 }
36692
36693
36694 function osmSimpleMultipolygonOuterMember(entity, graph) {
36695     if (entity.type !== 'way')
36696         return false;
36697
36698     var parents = graph.parentRelations(entity);
36699     if (parents.length !== 1)
36700         return false;
36701
36702     var parent = parents[0];
36703     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
36704         return false;
36705
36706     var members = parent.members, member, outerMember;
36707     for (var i = 0; i < members.length; i++) {
36708         member = members[i];
36709         if (!member.role || member.role === 'outer') {
36710             if (outerMember)
36711                 return false; // Not a simple multipolygon
36712             outerMember = member;
36713         }
36714     }
36715
36716     if (!outerMember)
36717         return false;
36718
36719     var outerEntity = graph.hasEntity(outerMember.id);
36720     if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length)
36721         return false;
36722
36723     return outerEntity;
36724 }
36725
36726
36727 // Join `array` into sequences of connecting ways.
36728 //
36729 // Segments which share identical start/end nodes will, as much as possible,
36730 // be connected with each other.
36731 //
36732 // The return value is a nested array. Each constituent array contains elements
36733 // of `array` which have been determined to connect. Each consitituent array
36734 // also has a `nodes` property whose value is an ordered array of member nodes,
36735 // with appropriate order reversal and start/end coordinate de-duplication.
36736 //
36737 // Members of `array` must have, at minimum, `type` and `id` properties.
36738 // Thus either an array of `osmWay`s or a relation member array may be
36739 // used.
36740 //
36741 // If an member has a `tags` property, its tags will be reversed via
36742 // `actionReverse` in the output.
36743 //
36744 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
36745 // false) and non-way members are ignored.
36746 //
36747 function osmJoinWays(array, graph) {
36748     var joined = [], member, current, nodes, first, last, i, how, what;
36749
36750     array = array.filter(function(member) {
36751         return member.type === 'way' && graph.hasEntity(member.id);
36752     });
36753
36754     function resolve(member) {
36755         return graph.childNodes(graph.entity(member.id));
36756     }
36757
36758     function reverse(member) {
36759         return member.tags ? actionReverse(member.id, { reverseOneway: true })(graph).entity(member.id) : member;
36760     }
36761
36762     while (array.length) {
36763         member = array.shift();
36764         current = [member];
36765         current.nodes = nodes = resolve(member).slice();
36766         joined.push(current);
36767
36768         while (array.length && lodash.first(nodes) !== lodash.last(nodes)) {
36769             first = lodash.first(nodes);
36770             last  = lodash.last(nodes);
36771
36772             for (i = 0; i < array.length; i++) {
36773                 member = array[i];
36774                 what = resolve(member);
36775
36776                 if (last === lodash.first(what)) {
36777                     how  = nodes.push;
36778                     what = what.slice(1);
36779                     break;
36780                 } else if (last === lodash.last(what)) {
36781                     how  = nodes.push;
36782                     what = what.slice(0, -1).reverse();
36783                     member = reverse(member);
36784                     break;
36785                 } else if (first === lodash.last(what)) {
36786                     how  = nodes.unshift;
36787                     what = what.slice(0, -1);
36788                     break;
36789                 } else if (first === lodash.first(what)) {
36790                     how  = nodes.unshift;
36791                     what = what.slice(1).reverse();
36792                     member = reverse(member);
36793                     break;
36794                 } else {
36795                     what = how = null;
36796                 }
36797             }
36798
36799             if (!what)
36800                 break; // No more joinable ways.
36801
36802             how.apply(current, [member]);
36803             how.apply(nodes, what);
36804
36805             array.splice(i, 1);
36806         }
36807     }
36808
36809     return joined;
36810 }
36811
36812 function osmRelation() {
36813     if (!(this instanceof osmRelation)) {
36814         return (new osmRelation()).initialize(arguments);
36815     } else if (arguments.length) {
36816         this.initialize(arguments);
36817     }
36818 }
36819
36820
36821 osmEntity$$1.relation = osmRelation;
36822
36823 osmRelation.prototype = Object.create(osmEntity$$1.prototype);
36824
36825
36826 osmRelation.creationOrder = function(a, b) {
36827     var aId = parseInt(osmEntity$$1.id.toOSM(a.id), 10);
36828     var bId = parseInt(osmEntity$$1.id.toOSM(b.id), 10);
36829
36830     if (aId < 0 || bId < 0) return aId - bId;
36831     return bId - aId;
36832 };
36833
36834
36835 lodash.extend(osmRelation.prototype, {
36836     type: 'relation',
36837     members: [],
36838
36839
36840     copy: function(resolver, copies) {
36841         if (copies[this.id])
36842             return copies[this.id];
36843
36844         var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
36845
36846         var members = this.members.map(function(member) {
36847             return lodash.extend({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
36848         });
36849
36850         copy = copy.update({members: members});
36851         copies[this.id] = copy;
36852
36853         return copy;
36854     },
36855
36856
36857     extent: function(resolver, memo) {
36858         return resolver.transient(this, 'extent', function() {
36859             if (memo && memo[this.id]) return geoExtent$$1();
36860             memo = memo || {};
36861             memo[this.id] = true;
36862
36863             var extent$$1 = geoExtent$$1();
36864             for (var i = 0; i < this.members.length; i++) {
36865                 var member = resolver.hasEntity(this.members[i].id);
36866                 if (member) {
36867                     extent$$1._extend(member.extent(resolver, memo));
36868                 }
36869             }
36870             return extent$$1;
36871         });
36872     },
36873
36874
36875     geometry: function(graph) {
36876         return graph.transient(this, 'geometry', function() {
36877             return this.isMultipolygon() ? 'area' : 'relation';
36878         });
36879     },
36880
36881
36882     isDegenerate: function() {
36883         return this.members.length === 0;
36884     },
36885
36886
36887     // Return an array of members, each extended with an 'index' property whose value
36888     // is the member index.
36889     indexedMembers: function() {
36890         var result = new Array(this.members.length);
36891         for (var i = 0; i < this.members.length; i++) {
36892             result[i] = lodash.extend({}, this.members[i], {index: i});
36893         }
36894         return result;
36895     },
36896
36897
36898     // Return the first member with the given role. A copy of the member object
36899     // is returned, extended with an 'index' property whose value is the member index.
36900     memberByRole: function(role) {
36901         for (var i = 0; i < this.members.length; i++) {
36902             if (this.members[i].role === role) {
36903                 return lodash.extend({}, this.members[i], {index: i});
36904             }
36905         }
36906     },
36907
36908
36909     // Return the first member with the given id. A copy of the member object
36910     // is returned, extended with an 'index' property whose value is the member index.
36911     memberById: function(id) {
36912         for (var i = 0; i < this.members.length; i++) {
36913             if (this.members[i].id === id) {
36914                 return lodash.extend({}, this.members[i], {index: i});
36915             }
36916         }
36917     },
36918
36919
36920     // Return the first member with the given id and role. A copy of the member object
36921     // is returned, extended with an 'index' property whose value is the member index.
36922     memberByIdAndRole: function(id, role) {
36923         for (var i = 0; i < this.members.length; i++) {
36924             if (this.members[i].id === id && this.members[i].role === role) {
36925                 return lodash.extend({}, this.members[i], {index: i});
36926             }
36927         }
36928     },
36929
36930
36931     addMember: function(member, index) {
36932         var members = this.members.slice();
36933         members.splice(index === undefined ? members.length : index, 0, member);
36934         return this.update({members: members});
36935     },
36936
36937
36938     updateMember: function(member, index) {
36939         var members = this.members.slice();
36940         members.splice(index, 1, lodash.extend({}, members[index], member));
36941         return this.update({members: members});
36942     },
36943
36944
36945     removeMember: function(index) {
36946         var members = this.members.slice();
36947         members.splice(index, 1);
36948         return this.update({members: members});
36949     },
36950
36951
36952     removeMembersWithID: function(id) {
36953         var members = lodash.reject(this.members, function(m) { return m.id === id; });
36954         return this.update({members: members});
36955     },
36956
36957
36958     // Wherever a member appears with id `needle.id`, replace it with a member
36959     // with id `replacement.id`, type `replacement.type`, and the original role,
36960     // unless a member already exists with that id and role. Return an updated
36961     // relation.
36962     replaceMember: function(needle, replacement) {
36963         if (!this.memberById(needle.id))
36964             return this;
36965
36966         var members = [];
36967
36968         for (var i = 0; i < this.members.length; i++) {
36969             var member = this.members[i];
36970             if (member.id !== needle.id) {
36971                 members.push(member);
36972             } else if (!this.memberByIdAndRole(replacement.id, member.role)) {
36973                 members.push({id: replacement.id, type: replacement.type, role: member.role});
36974             }
36975         }
36976
36977         return this.update({members: members});
36978     },
36979
36980
36981     asJXON: function(changeset_id) {
36982         var r = {
36983             relation: {
36984                 '@id': this.osmId(),
36985                 '@version': this.version || 0,
36986                 member: lodash.map(this.members, function(member) {
36987                     return {
36988                         keyAttributes: {
36989                             type: member.type,
36990                             role: member.role,
36991                             ref: osmEntity$$1.id.toOSM(member.id)
36992                         }
36993                     };
36994                 }),
36995                 tag: lodash.map(this.tags, function(v, k) {
36996                     return { keyAttributes: { k: k, v: v } };
36997                 })
36998             }
36999         };
37000         if (changeset_id) r.relation['@changeset'] = changeset_id;
37001         return r;
37002     },
37003
37004
37005     asGeoJSON: function(resolver) {
37006         return resolver.transient(this, 'GeoJSON', function () {
37007             if (this.isMultipolygon()) {
37008                 return {
37009                     type: 'MultiPolygon',
37010                     coordinates: this.multipolygon(resolver)
37011                 };
37012             } else {
37013                 return {
37014                     type: 'FeatureCollection',
37015                     properties: this.tags,
37016                     features: this.members.map(function (member) {
37017                         return lodash.extend({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
37018                     })
37019                 };
37020             }
37021         });
37022     },
37023
37024
37025     area: function(resolver) {
37026         return resolver.transient(this, 'area', function() {
37027             return area(this.asGeoJSON(resolver));
37028         });
37029     },
37030
37031
37032     isMultipolygon: function() {
37033         return this.tags.type === 'multipolygon';
37034     },
37035
37036
37037     isComplete: function(resolver) {
37038         for (var i = 0; i < this.members.length; i++) {
37039             if (!resolver.hasEntity(this.members[i].id)) {
37040                 return false;
37041             }
37042         }
37043         return true;
37044     },
37045
37046
37047     isRestriction: function() {
37048         return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
37049     },
37050
37051
37052     // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
37053     // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
37054     //
37055     // This corresponds to the structure needed for rendering a multipolygon path using a
37056     // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
37057     //
37058     // In the case of invalid geometries, this function will still return a result which
37059     // includes the nodes of all way members, but some Nds may be unclosed and some inner
37060     // rings not matched with the intended outer ring.
37061     //
37062     multipolygon: function(resolver) {
37063         var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
37064             inners = this.members.filter(function(m) { return 'inner' === m.role; });
37065
37066         outers = osmJoinWays(outers, resolver);
37067         inners = osmJoinWays(inners, resolver);
37068
37069         outers = outers.map(function(outer) { return lodash.map(outer.nodes, 'loc'); });
37070         inners = inners.map(function(inner) { return lodash.map(inner.nodes, 'loc'); });
37071
37072         var result = outers.map(function(o) {
37073             // Heuristic for detecting counterclockwise winding order. Assumes
37074             // that OpenStreetMap polygons are not hemisphere-spanning.
37075             return [area({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
37076         });
37077
37078         function findOuter(inner) {
37079             var o, outer;
37080
37081             for (o = 0; o < outers.length; o++) {
37082                 outer = outers[o];
37083                 if (geoPolygonContainsPolygon(outer, inner))
37084                     return o;
37085             }
37086
37087             for (o = 0; o < outers.length; o++) {
37088                 outer = outers[o];
37089                 if (geoPolygonIntersectsPolygon(outer, inner, false))
37090                     return o;
37091             }
37092         }
37093
37094         for (var i = 0; i < inners.length; i++) {
37095             var inner = inners[i];
37096
37097             if (area({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
37098                 inner = inner.reverse();
37099             }
37100
37101             var o = findOuter(inners[i]);
37102             if (o !== undefined)
37103                 result[o].push(inners[i]);
37104             else
37105                 result.push([inners[i]]); // Invalid geometry
37106         }
37107
37108         return result;
37109     }
37110 });
37111
37112 function osmLanes(entity) {
37113     if (entity.type !== 'way') return null;
37114     if (!entity.tags.highway) return null;
37115
37116     var tags = entity.tags;
37117     var isOneWay = entity.isOneWay();
37118     var laneCount = getLaneCount(tags, isOneWay);
37119     var maxspeed = parseMaxspeed(tags);
37120
37121     var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
37122     var forward = laneDirections.forward;
37123     var backward = laneDirections.backward;
37124     var bothways = laneDirections.bothways;
37125
37126     // parse the piped string 'x|y|z' format
37127     var turnLanes = {};
37128     turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
37129     turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
37130     turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
37131
37132     var maxspeedLanes = {};
37133     maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
37134     maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
37135     maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
37136
37137     var psvLanes = {};
37138     psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
37139     psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
37140     psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
37141
37142     var busLanes = {};
37143     busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
37144     busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
37145     busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
37146
37147     var taxiLanes = {};
37148     taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
37149     taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
37150     taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
37151
37152     var hovLanes = {};
37153     hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
37154     hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
37155     hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
37156
37157     var hgvLanes = {};
37158     hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
37159     hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
37160     hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
37161
37162     var bicyclewayLanes = {};
37163     bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
37164     bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
37165     bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
37166
37167     var lanesObj = {
37168         forward: [],
37169         backward: [],
37170         unspecified: []
37171     };
37172
37173     // map forward/backward/unspecified of each lane type to lanesObj
37174     mapToLanesObj(lanesObj, turnLanes, 'turnLane');
37175     mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
37176     mapToLanesObj(lanesObj, psvLanes, 'psv');
37177     mapToLanesObj(lanesObj, busLanes, 'bus');
37178     mapToLanesObj(lanesObj, taxiLanes, 'taxi');
37179     mapToLanesObj(lanesObj, hovLanes, 'hov');
37180     mapToLanesObj(lanesObj, hgvLanes, 'hgv');
37181     mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
37182
37183     return {
37184         metadata: {
37185             count: laneCount,
37186             oneway: isOneWay,
37187             forward: forward,
37188             backward: backward,
37189             bothways: bothways,
37190             turnLanes: turnLanes,
37191             maxspeed: maxspeed,
37192             maxspeedLanes: maxspeedLanes,
37193             psvLanes: psvLanes,
37194             busLanes: busLanes,
37195             taxiLanes: taxiLanes,
37196             hovLanes: hovLanes,
37197             hgvLanes: hgvLanes,
37198             bicyclewayLanes: bicyclewayLanes
37199         },
37200         lanes: lanesObj
37201     };
37202 }
37203
37204
37205 function getLaneCount(tags, isOneWay) {
37206     var count;
37207     if (tags.lanes) {
37208         count = parseInt(tags.lanes, 10);
37209         if (count > 0) {
37210             return count;
37211         }
37212     }
37213
37214
37215     switch (tags.highway) {
37216         case 'trunk':
37217         case 'motorway':
37218             count = isOneWay ? 2 : 4;
37219             break;
37220         default:
37221             count = isOneWay ? 1 : 2;
37222             break;
37223     }
37224
37225     return count;
37226 }
37227
37228
37229 function parseMaxspeed(tags) {
37230     var maxspeed = tags.maxspeed;
37231     if (lodash.isNumber(maxspeed)) return maxspeed;
37232     if (lodash.isString(maxspeed)) {
37233         maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
37234         if (!maxspeed) return;
37235         return parseInt(maxspeed, 10);
37236     }
37237 }
37238
37239
37240 function parseLaneDirections(tags, isOneWay, laneCount) {
37241     var forward = parseInt(tags['lanes:forward'], 10);
37242     var backward = parseInt(tags['lanes:backward'], 10);
37243     var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
37244
37245     if (parseInt(tags.oneway, 10) === -1) {
37246         forward = 0;
37247         bothways = 0;
37248         backward = laneCount;
37249     }
37250     else if (isOneWay) {
37251         forward = laneCount;
37252         bothways = 0;
37253         backward = 0;
37254     }
37255     else if (lodash.isNaN(forward) && lodash.isNaN(backward)) {
37256         backward = Math.floor((laneCount - bothways) / 2);
37257         forward = laneCount - bothways - backward;
37258     }
37259     else if (lodash.isNaN(forward)) {
37260         if (backward > laneCount - bothways) {
37261             backward = laneCount - bothways;
37262         }
37263         forward = laneCount - bothways - backward;
37264     }
37265     else if (lodash.isNaN(backward)) {
37266         if (forward > laneCount - bothways) {
37267             forward = laneCount - bothways;
37268         }
37269         backward = laneCount - bothways - forward;
37270     }
37271     return {
37272         forward: forward,
37273         backward: backward,
37274         bothways: bothways
37275     };
37276 }
37277
37278
37279 function parseTurnLanes(tag){
37280     if (!tag) return;
37281
37282     var validValues = [
37283         'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
37284         'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
37285     ];
37286
37287     return tag.split('|')
37288         .map(function (s) {
37289             if (s === '') s = 'none';
37290             return s.split(';')
37291                 .map(function (d) {
37292                     return validValues.indexOf(d) === -1 ? 'unknown': d;
37293                 });
37294         });
37295 }
37296
37297
37298 function parseMaxspeedLanes(tag, maxspeed) {
37299     if (!tag) return;
37300
37301     return tag.split('|')
37302         .map(function (s) {
37303             if (s === 'none') return s;
37304             var m = parseInt(s, 10);
37305             if (s === '' || m === maxspeed) return null;
37306             return lodash.isNaN(m) ? 'unknown': m;
37307         });
37308 }
37309
37310
37311 function parseMiscLanes(tag) {
37312     if (!tag) return;
37313
37314     var validValues = [
37315         'yes', 'no', 'designated'
37316     ];
37317
37318     return tag.split('|')
37319         .map(function (s) {
37320             if (s === '') s = 'no';
37321             return validValues.indexOf(s) === -1 ? 'unknown': s;
37322         });
37323 }
37324
37325
37326 function parseBicycleWay(tag) {
37327     if (!tag) return;
37328
37329     var validValues = [
37330         'yes', 'no', 'designated', 'lane'
37331     ];
37332
37333     return tag.split('|')
37334         .map(function (s) {
37335             if (s === '') s = 'no';
37336             return validValues.indexOf(s) === -1 ? 'unknown': s;
37337         });
37338 }
37339
37340
37341 function mapToLanesObj(lanesObj, data, key) {
37342     if (data.forward) data.forward.forEach(function(l, i) {
37343         if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
37344         lanesObj.forward[i][key] = l;
37345     });
37346     if (data.backward) data.backward.forEach(function(l, i) {
37347         if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
37348         lanesObj.backward[i][key] = l;
37349     });
37350     if (data.unspecified) data.unspecified.forEach(function(l, i) {
37351         if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
37352         lanesObj.unspecified[i][key] = l;
37353     });
37354 }
37355
37356 var translations = Object.create(null);
37357
37358 var currentLocale = 'en';
37359 var textDirection = 'ltr';
37360
37361 function setLocale(_) {
37362     if (translations[_] !== undefined) {
37363         currentLocale = _;
37364     } else if (translations[_.split('-')[0]]) {
37365         currentLocale = _.split('-')[0];
37366     }
37367 }
37368
37369 function addTranslation(id, value) {
37370     translations[id] = value;
37371 }
37372
37373 /**
37374  * Given a string identifier, try to find that string in the current
37375  * language, and return it.
37376  *
37377  * @param {string} s string identifier
37378  * @returns {string?} locale string
37379  */
37380 function t(s, o, loc) {
37381     loc = loc || currentLocale;
37382
37383     var path = s
37384         .split('.')
37385         .map(function(s) { return s.replace('<TX_DOT>', '.'); })
37386         .reverse();
37387
37388     var rep = translations[loc];
37389
37390     while (rep !== undefined && path.length) rep = rep[path.pop()];
37391
37392     if (rep !== undefined) {
37393         if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
37394         return rep;
37395     }
37396
37397     if (loc !== 'en') {
37398         return t(s, o, 'en');
37399     }
37400
37401     if (o && 'default' in o) {
37402         return o.default;
37403     }
37404
37405     var missing = 'Missing ' + loc + ' translation: ' + s;
37406     if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
37407
37408     return missing;
37409 }
37410
37411 /**
37412  * Given string 'ltr' or 'rtl', save that setting
37413  *
37414  * @param {string} s ltr or rtl
37415  */
37416
37417 function setTextDirection(dir) {
37418     textDirection = dir;
37419 }
37420
37421 var detected;
37422
37423 function utilDetect(force) {
37424     if (detected && !force) return detected;
37425     detected = {};
37426
37427     var ua = navigator.userAgent,
37428         m = null;
37429
37430     m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i);   // Edge
37431     if (m !== null) {
37432         detected.browser = m[1];
37433         detected.version = m[2];
37434     }
37435     if (!detected.browser) {
37436         m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i);   // IE11
37437         if (m !== null) {
37438             detected.browser = 'msie';
37439             detected.version = m[1];
37440         }
37441     }
37442     if (!detected.browser) {
37443         m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i);   // Opera 15+
37444         if (m !== null) {
37445             detected.browser = 'Opera';
37446             detected.version = m[2];
37447         }
37448     }
37449     if (!detected.browser) {
37450         m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
37451         if (m !== null) {
37452             detected.browser = m[1];
37453             detected.version = m[2];
37454             m = ua.match(/version\/([\.\d]+)/i);
37455             if (m !== null) detected.version = m[1];
37456         }
37457     }
37458     if (!detected.browser) {
37459         detected.browser = navigator.appName;
37460         detected.version = navigator.appVersion;
37461     }
37462
37463     // keep major.minor version only..
37464     detected.version = detected.version.split(/\W/).slice(0,2).join('.');
37465
37466     if (detected.browser.toLowerCase() === 'msie') {
37467         detected.ie = true;
37468         detected.browser = 'Internet Explorer';
37469         detected.support = parseFloat(detected.version) >= 11;
37470     } else {
37471         detected.ie = false;
37472         detected.support = true;
37473     }
37474
37475     // Added due to incomplete svg style support. See #715
37476     detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
37477
37478     detected.locale = (navigator.language || navigator.userLanguage || 'en-US');
37479     detected.language = detected.locale.split('-')[0];
37480
37481     // Search `navigator.languages` for a better locale.. Prefer the first language,
37482     // unless the second language is a culture-specific version of the first one, see #3842
37483     if (navigator.languages && navigator.languages.length > 0) {
37484         var code0 = navigator.languages[0],
37485             parts0 = code0.split('-');
37486
37487         detected.locale = code0;
37488         detected.language = parts0[0];
37489
37490         if (navigator.languages.length > 1 && parts0.length === 1) {
37491             var code1 = navigator.languages[1],
37492                 parts1 = code1.split('-');
37493
37494             if (parts1[0] === parts0[0]) {
37495                 detected.locale = code1;
37496             }
37497         }
37498     }
37499
37500     // Loaded locale is stored in currentLocale
37501     // return that instead (except in the situation where 'en' might override 'en-US')
37502     var loadedLocale = currentLocale || 'en';
37503     if (loadedLocale !== 'en') {
37504         detected.locale = loadedLocale;
37505         detected.language = detected.locale.split('-')[0];
37506     }
37507
37508     // detect text direction
37509     var q = utilStringQs(window.location.hash.substring(1));
37510     var lang = dataLocales[detected.locale];
37511     if ((lang && lang.rtl) || (q.rtl === 'true')) {
37512         detected.textDirection = 'rtl';
37513     } else {
37514         detected.textDirection = 'ltr';
37515     }
37516     setTextDirection(detected.textDirection);
37517
37518     // detect host
37519     var loc = window.top.location;
37520     var origin = loc.origin;
37521     if (!origin) {  // for unpatched IE11
37522         origin = loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port: '');
37523     }
37524
37525     detected.host = origin + loc.pathname;
37526
37527     detected.filedrop = (window.FileReader && 'ondrop' in window);
37528
37529     function nav(x) {
37530         return navigator.userAgent.indexOf(x) !== -1;
37531     }
37532
37533     if (nav('Win')) {
37534         detected.os = 'win';
37535         detected.platform = 'Windows';
37536     }
37537     else if (nav('Mac')) {
37538         detected.os = 'mac';
37539         detected.platform = 'Macintosh';
37540     }
37541     else if (nav('X11') || nav('Linux')) {
37542         detected.os = 'linux';
37543         detected.platform = 'Linux';
37544     }
37545     else {
37546         detected.os = 'win';
37547         detected.platform = 'Unknown';
37548     }
37549
37550     return detected;
37551 }
37552
37553 var remove$1 = removeDiacritics;
37554
37555 var replacementList = [
37556   {
37557     base: ' ',
37558     chars: "\u00A0",
37559   }, {
37560     base: '0',
37561     chars: "\u07C0",
37562   }, {
37563     base: 'A',
37564     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",
37565   }, {
37566     base: 'AA',
37567     chars: "\uA732",
37568   }, {
37569     base: 'AE',
37570     chars: "\u00C6\u01FC\u01E2",
37571   }, {
37572     base: 'AO',
37573     chars: "\uA734",
37574   }, {
37575     base: 'AU',
37576     chars: "\uA736",
37577   }, {
37578     base: 'AV',
37579     chars: "\uA738\uA73A",
37580   }, {
37581     base: 'AY',
37582     chars: "\uA73C",
37583   }, {
37584     base: 'B',
37585     chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
37586   }, {
37587     base: 'C',
37588     chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
37589   }, {
37590     base: 'D',
37591     chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
37592   }, {
37593     base: 'Dh',
37594     chars: "\u00D0",
37595   }, {
37596     base: 'DZ',
37597     chars: "\u01F1\u01C4",
37598   }, {
37599     base: 'Dz',
37600     chars: "\u01F2\u01C5",
37601   }, {
37602     base: 'E',
37603     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",
37604   }, {
37605     base: 'F',
37606     chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
37607   }, {
37608     base: 'G',
37609     chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
37610   }, {
37611     base: 'H',
37612     chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
37613   }, {
37614     base: 'I',
37615     chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
37616   }, {
37617     base: 'J',
37618     chars: "\u24BF\uFF2A\u0134\u0248\u0237",
37619   }, {
37620     base: 'K',
37621     chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
37622   }, {
37623     base: 'L',
37624     chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
37625   }, {
37626     base: 'LJ',
37627     chars: "\u01C7",
37628   }, {
37629     base: 'Lj',
37630     chars: "\u01C8",
37631   }, {
37632     base: 'M',
37633     chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
37634   }, {
37635     base: 'N',
37636     chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
37637   }, {
37638     base: 'NJ',
37639     chars: "\u01CA",
37640   }, {
37641     base: 'Nj',
37642     chars: "\u01CB",
37643   }, {
37644     base: 'O',
37645     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",
37646   }, {
37647     base: 'OE',
37648     chars: "\u0152",
37649   }, {
37650     base: 'OI',
37651     chars: "\u01A2",
37652   }, {
37653     base: 'OO',
37654     chars: "\uA74E",
37655   }, {
37656     base: 'OU',
37657     chars: "\u0222",
37658   }, {
37659     base: 'P',
37660     chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
37661   }, {
37662     base: 'Q',
37663     chars: "\u24C6\uFF31\uA756\uA758\u024A",
37664   }, {
37665     base: 'R',
37666     chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
37667   }, {
37668     base: 'S',
37669     chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
37670   }, {
37671     base: 'T',
37672     chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
37673   }, {
37674     base: 'Th',
37675     chars: "\u00DE",
37676   }, {
37677     base: 'TZ',
37678     chars: "\uA728",
37679   }, {
37680     base: 'U',
37681     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",
37682   }, {
37683     base: 'V',
37684     chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
37685   }, {
37686     base: 'VY',
37687     chars: "\uA760",
37688   }, {
37689     base: 'W',
37690     chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
37691   }, {
37692     base: 'X',
37693     chars: "\u24CD\uFF38\u1E8A\u1E8C",
37694   }, {
37695     base: 'Y',
37696     chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
37697   }, {
37698     base: 'Z',
37699     chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
37700   }, {
37701     base: 'a',
37702     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",
37703   }, {
37704     base: 'aa',
37705     chars: "\uA733",
37706   }, {
37707     base: 'ae',
37708     chars: "\u00E6\u01FD\u01E3",
37709   }, {
37710     base: 'ao',
37711     chars: "\uA735",
37712   }, {
37713     base: 'au',
37714     chars: "\uA737",
37715   }, {
37716     base: 'av',
37717     chars: "\uA739\uA73B",
37718   }, {
37719     base: 'ay',
37720     chars: "\uA73D",
37721   }, {
37722     base: 'b',
37723     chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
37724   }, {
37725     base: 'c',
37726     chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
37727   }, {
37728     base: 'd',
37729     chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
37730   }, {
37731     base: 'dh',
37732     chars: "\u00F0",
37733   }, {
37734     base: 'dz',
37735     chars: "\u01F3\u01C6",
37736   }, {
37737     base: 'e',
37738     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",
37739   }, {
37740     base: 'f',
37741     chars: "\u24D5\uFF46\u1E1F\u0192",
37742   }, {
37743     base: 'ff',
37744     chars: "\uFB00",
37745   }, {
37746     base: 'fi',
37747     chars: "\uFB01",
37748   }, {
37749     base: 'fl',
37750     chars: "\uFB02",
37751   }, {
37752     base: 'ffi',
37753     chars: "\uFB03",
37754   }, {
37755     base: 'ffl',
37756     chars: "\uFB04",
37757   }, {
37758     base: 'g',
37759     chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
37760   }, {
37761     base: 'h',
37762     chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
37763   }, {
37764     base: 'hv',
37765     chars: "\u0195",
37766   }, {
37767     base: 'i',
37768     chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
37769   }, {
37770     base: 'j',
37771     chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
37772   }, {
37773     base: 'k',
37774     chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
37775   }, {
37776     base: 'l',
37777     chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
37778   }, {
37779     base: 'lj',
37780     chars: "\u01C9",
37781   }, {
37782     base: 'm',
37783     chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
37784   }, {
37785     base: 'n',
37786     chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
37787   }, {
37788     base: 'nj',
37789     chars: "\u01CC",
37790   }, {
37791     base: 'o',
37792     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",
37793   }, {
37794     base: 'oe',
37795     chars: "\u0153",
37796   }, {
37797     base: 'oi',
37798     chars: "\u01A3",
37799   }, {
37800     base: 'oo',
37801     chars: "\uA74F",
37802   }, {
37803     base: 'ou',
37804     chars: "\u0223",
37805   }, {
37806     base: 'p',
37807     chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
37808   }, {
37809     base: 'q',
37810     chars: "\u24E0\uFF51\u024B\uA757\uA759",
37811   }, {
37812     base: 'r',
37813     chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
37814   }, {
37815     base: 's',
37816     chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
37817   }, {
37818     base: 'ss',
37819     chars: "\xDF",
37820   }, {
37821     base: 't',
37822     chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
37823   }, {
37824     base: 'th',
37825     chars: "\u00FE",
37826   }, {
37827     base: 'tz',
37828     chars: "\uA729",
37829   }, {
37830     base: 'u',
37831     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",
37832   }, {
37833     base: 'v',
37834     chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
37835   }, {
37836     base: 'vy',
37837     chars: "\uA761",
37838   }, {
37839     base: 'w',
37840     chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
37841   }, {
37842     base: 'x',
37843     chars: "\u24E7\uFF58\u1E8B\u1E8D",
37844   }, {
37845     base: 'y',
37846     chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
37847   }, {
37848     base: 'z',
37849     chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
37850   }
37851 ];
37852
37853 var diacriticsMap = {};
37854 for (var i = 0; i < replacementList.length; i += 1) {
37855   var chars = replacementList[i].chars;
37856   for (var j = 0; j < chars.length; j += 1) {
37857     diacriticsMap[chars[j]] = replacementList[i].base;
37858   }
37859 }
37860
37861 function removeDiacritics(str) {
37862   return str.replace(/[^\u0000-\u007e]/g, function(c) {
37863     return diacriticsMap[c] || c;
37864   });
37865 }
37866
37867 // see https://github.com/openstreetmap/iD/pull/3707
37868 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60
37869
37870 var chars$1 = {
37871     // madda above alef
37872     1570: { initial: 'آ‎', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' },
37873
37874     // hamza above and below alef
37875     1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' },
37876     // 1572 is ؤ
37877     1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' },
37878     // 1574 is ئ
37879     1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' },
37880     1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' },
37881
37882     // 1577 ة
37883     1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' },
37884
37885     1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' },
37886     1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' },
37887     1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' },
37888     1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' },
37889     1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' },
37890     1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' },
37891     1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' },
37892     1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' },
37893     1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' },
37894     1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' },
37895     1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' },
37896     1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' },
37897     1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' },
37898     1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' },
37899     1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' },
37900     1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' },
37901     1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' },
37902     1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' },
37903
37904     // 1595 ػ - may be very rare
37905
37906     1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' },
37907     1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' },
37908     1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' },
37909     1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' },
37910     1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' },
37911     1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' },
37912     1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' },
37913
37914     // 1609 ى
37915     1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' },
37916     // 1610 ي
37917     1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' },
37918
37919     // short vowel sounds / tashkil markings
37920
37921     1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' },
37922
37923     1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' },
37924     1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' },
37925     1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' },
37926     1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' },
37927     1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' },
37928     5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' }
37929 };
37930
37931 var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0780-\u07BF]/;
37932
37933 function fixRTLTextForSvg(inputText) {
37934     var context = true;
37935     var ret = '';
37936     var rtlBuffer = [];
37937     var arabicRegex = /[\u0600-\u06FF]/g;
37938     var arabicTashkil = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/;
37939     var thaanaVowel = /[\u07A6-\u07B0]/;
37940     var hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/;
37941
37942     if (!arabicRegex.test(inputText)) {
37943         // Hebrew or Thaana RTL script
37944         for (var n = 0; n < inputText.length; n++) {
37945             var c = inputText[n];
37946             if ((thaanaVowel.test(c) || hebrewSign.test(c)) && rtlBuffer.length) {
37947                 rtlBuffer[rtlBuffer.length - 1] += c;
37948             } else if (rtlRegex.test(c)) {
37949                 rtlBuffer.push(c);
37950             } else if (c === ' ' && rtlBuffer.length) {
37951                 // whitespace within RTL text
37952                 rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
37953             } else {
37954                 // non-RTL character
37955                 ret += rtlBuffer.reverse().join('') + c;
37956                 rtlBuffer = [];
37957             }
37958         }
37959     } else {
37960         for (var i = 0, l = inputText.length; i < l; i++) {
37961             var code = inputText[i].charCodeAt(0);
37962             var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0;
37963
37964             if (!chars$1[code]) {
37965                 if (code === 32 && rtlBuffer.length) {
37966                     // whitespace
37967                     rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
37968                 } else if (arabicTashkil.test(inputText[i]) && rtlBuffer.length) {
37969                     // tashkil mark
37970                     rtlBuffer[rtlBuffer.length - 1] += inputText[i];
37971                 } else {
37972                     // non-RTL character
37973                     ret += rtlBuffer.reverse().join('') + inputText[i];
37974                     rtlBuffer = [];
37975                 }
37976                 continue;
37977             }
37978             if (context) {
37979                 if (i === l - 1 || nextCode === 32) {
37980                     rtlBuffer.push(chars$1[code].isolated);
37981                 } else {
37982                     // special case for لا
37983                     if (code === 1604 && nextCode === 1575) {
37984                         rtlBuffer.push(chars$1[5000].initial);
37985                         i++;
37986                         context = true;
37987                         continue;
37988                     }
37989                     rtlBuffer.push(chars$1[code].initial);
37990                 }
37991             } else {
37992                 if (i === l - 1 || nextCode === 32){
37993                     rtlBuffer.push(chars$1[code].final);
37994                 } else {
37995                     // special case for ﻼ
37996                     if (code === 1604 && nextCode === 1575){
37997                         rtlBuffer.push(chars$1[5000].final);
37998                         i++;
37999                         context = true;
38000                         continue;
38001                     }
38002                     if (chars$1[code].medial === ''){
38003                         rtlBuffer.push(chars$1[code].final);
38004                     } else {
38005                         rtlBuffer.push(chars$1[code].medial);
38006                     }
38007                 }
38008             }
38009             context = (chars$1[code].medial === '') || nextCode === 32;
38010         }
38011     }
38012     ret += rtlBuffer.reverse().join('');
38013     return ret;
38014 }
38015
38016 function utilTagText(entity) {
38017     return entries(entity.tags).map(function(e) {
38018         return e.key + '=' + e.value;
38019     }).join(', ');
38020 }
38021
38022
38023 function utilEntitySelector(ids) {
38024     return ids.length ? '.' + ids.join(',.') : 'nothing';
38025 }
38026
38027
38028 function utilEntityOrMemberSelector(ids, graph) {
38029     var s = utilEntitySelector(ids);
38030
38031     ids.forEach(function(id) {
38032         var entity = graph.hasEntity(id);
38033         if (entity && entity.type === 'relation') {
38034             entity.members.forEach(function(member) {
38035                 s += ',.' + member.id;
38036             });
38037         }
38038     });
38039
38040     return s;
38041 }
38042
38043
38044 function utilGetAllNodes(ids, graph) {
38045     var seen = {};
38046     var nodes = [];
38047     ids.forEach(getNodes);
38048     return nodes;
38049
38050     function getNodes(id) {
38051         if (seen[id]) return;
38052         seen[id] = true;
38053
38054         var entity = graph.hasEntity(id);
38055         if (!entity) return;
38056
38057         if (entity.type === 'node') {
38058             nodes.push(entity);
38059         } else if (entity.type === 'way') {
38060             entity.nodes.forEach(getNodes);
38061         } else {
38062             entity.members.map(function(member) { return member.id; }).forEach(getNodes);
38063         }
38064     }
38065 }
38066
38067
38068 function utilDisplayName(entity) {
38069     var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
38070         name = entity.tags[localizedNameKey] || entity.tags.name || '',
38071         network = entity.tags.cycle_network || entity.tags.network;
38072
38073     if (!name && entity.tags.ref) {
38074         name = entity.tags.ref;
38075         if (network) {
38076             name = network + ' ' + name;
38077         }
38078     }
38079
38080     return name;
38081 }
38082
38083
38084 function utilDisplayNameForPath(entity) {
38085     var name = utilDisplayName(entity);
38086     var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1;
38087
38088     if (!isFirefox && name && rtlRegex.test(name)) {
38089         name = fixRTLTextForSvg(name);
38090     }
38091
38092     return name;
38093 }
38094
38095
38096 function utilDisplayType(id) {
38097     return {
38098         n: t('inspector.node'),
38099         w: t('inspector.way'),
38100         r: t('inspector.relation')
38101     }[id.charAt(0)];
38102 }
38103
38104
38105 function utilStringQs(str) {
38106     return str.split('&').reduce(function(obj, pair){
38107         var parts = pair.split('=');
38108         if (parts.length === 2) {
38109             obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
38110         }
38111         return obj;
38112     }, {});
38113 }
38114
38115
38116 function utilQsString(obj, noencode) {
38117     function softEncode(s) {
38118       // encode everything except special characters used in certain hash parameters:
38119       // "/" in map states, ":", ",", {" and "}" in background
38120       return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
38121     }
38122     return Object.keys(obj).sort().map(function(key) {
38123         return encodeURIComponent(key) + '=' + (
38124             noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
38125     }).join('&');
38126 }
38127
38128
38129 function utilPrefixDOMProperty(property) {
38130     var prefixes = ['webkit', 'ms', 'moz', 'o'],
38131         i = -1,
38132         n = prefixes.length,
38133         s = document.body;
38134
38135     if (property in s)
38136         return property;
38137
38138     property = property.substr(0, 1).toUpperCase() + property.substr(1);
38139
38140     while (++i < n)
38141         if (prefixes[i] + property in s)
38142             return prefixes[i] + property;
38143
38144     return false;
38145 }
38146
38147
38148 function utilPrefixCSSProperty(property) {
38149     var prefixes = ['webkit', 'ms', 'Moz', 'O'],
38150         i = -1,
38151         n = prefixes.length,
38152         s = document.body.style;
38153
38154     if (property.toLowerCase() in s)
38155         return property.toLowerCase();
38156
38157     while (++i < n)
38158         if (prefixes[i] + property in s)
38159             return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
38160
38161     return false;
38162 }
38163
38164
38165 var transformProperty;
38166 function utilSetTransform(el, x, y, scale) {
38167     var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
38168         translate = utilDetect().opera ?
38169             'translate('   + x + 'px,' + y + 'px)' :
38170             'translate3d(' + x + 'px,' + y + 'px,0)';
38171     return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
38172 }
38173
38174
38175 // Calculates Levenshtein distance between two strings
38176 // see:  https://en.wikipedia.org/wiki/Levenshtein_distance
38177 // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents.
38178 function utilEditDistance(a, b) {
38179     a = remove$1(a.toLowerCase());
38180     b = remove$1(b.toLowerCase());
38181     if (a.length === 0) return b.length;
38182     if (b.length === 0) return a.length;
38183     var matrix = [];
38184     for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
38185     for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
38186     for (i = 1; i <= b.length; i++) {
38187         for (j = 1; j <= a.length; j++) {
38188             if (b.charAt(i-1) === a.charAt(j-1)) {
38189                 matrix[i][j] = matrix[i-1][j-1];
38190             } else {
38191                 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
38192                     Math.min(matrix[i][j-1] + 1, // insertion
38193                     matrix[i-1][j] + 1)); // deletion
38194             }
38195         }
38196     }
38197     return matrix[b.length][a.length];
38198 }
38199
38200
38201 // a d3.mouse-alike which
38202 // 1. Only works on HTML elements, not SVG
38203 // 2. Does not cause style recalculation
38204 function utilFastMouse(container) {
38205     var rect = container.getBoundingClientRect(),
38206         rectLeft = rect.left,
38207         rectTop = rect.top,
38208         clientLeft = +container.clientLeft,
38209         clientTop = +container.clientTop;
38210     if (textDirection === 'rtl') {
38211         rectLeft = 0;
38212     }
38213     return function(e) {
38214         return [
38215             e.clientX - rectLeft - clientLeft,
38216             e.clientY - rectTop - clientTop];
38217     };
38218 }
38219
38220
38221 /* eslint-disable no-proto */
38222 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
38223 /* eslint-enable no-proto */
38224
38225
38226 function utilAsyncMap(inputs, func, callback) {
38227     var remaining = inputs.length,
38228         results = [],
38229         errors = [];
38230
38231     inputs.forEach(function(d, i) {
38232         func(d, function done(err, data) {
38233             errors[i] = err;
38234             results[i] = data;
38235             remaining--;
38236             if (!remaining) callback(errors, results);
38237         });
38238     });
38239 }
38240
38241
38242 // wraps an index to an interval [0..length-1]
38243 function utilWrap(index, length) {
38244     if (index < 0)
38245         index += Math.ceil(-index/length)*length;
38246     return index % length;
38247 }
38248
38249
38250 /**
38251  * a replacement for functor
38252  *
38253  * @param {*} value any value
38254  * @returns {Function} a function that returns that value or the value if it's a function
38255  */
38256 function utilFunctor(value) {
38257     if (typeof value === 'function') return value;
38258     return function() {
38259         return value;
38260     };
38261 }
38262
38263
38264 function utilNoAuto(selection$$1) {
38265     return selection$$1
38266         .attr('autocomplete', 'off')
38267         .attr('autocorrect', 'off')
38268         .attr('autocapitalize', 'off')
38269         .attr('spellcheck', 'false');
38270 }
38271
38272 // Like selection.property('value', ...), but avoids no-op value sets,
38273 // which can result in layout/repaint thrashing in some situations.
38274 function utilGetSetValue(selection, value) {
38275     function d3_selection_value(value) {
38276         function valueNull() {
38277             delete this.value;
38278         }
38279
38280         function valueConstant() {
38281             if (this.value !== value) {
38282                 this.value = value;
38283             }
38284         }
38285
38286         function valueFunction() {
38287             var x = value.apply(this, arguments);
38288             if (x == null) {
38289                 delete this.value;
38290             } else if (this.value !== x) {
38291                 this.value = x;
38292             }
38293         }
38294
38295         return value == null
38296             ? valueNull : (typeof value === 'function'
38297             ? valueFunction : valueConstant);
38298     }
38299
38300     if (arguments.length === 1) {
38301         return selection.property('value');
38302     }
38303
38304     return selection.each(d3_selection_value(value));
38305 }
38306
38307 // Copies a variable number of methods from source to target.
38308 function utilRebind(target, source) {
38309     var i = 1, n = arguments.length, method;
38310     while (++i < n) {
38311         target[method = arguments[i]] = d3_rebind(target, source, source[method]);
38312     }
38313     return target;
38314 }
38315
38316 // Method is assumed to be a standard D3 getter-setter:
38317 // If passed with no arguments, gets the value.
38318 // If passed with arguments, sets the value and returns the target.
38319 function d3_rebind(target, source, method) {
38320     return function() {
38321         var value = method.apply(source, arguments);
38322         return value === source ? target : value;
38323     };
38324 }
38325
38326 // A per-domain session mutex backed by a cookie and dead man's
38327 // switch. If the session crashes, the mutex will auto-release
38328 // after 5 seconds.
38329
38330 function utilSessionMutex(name) {
38331     var mutex = {},
38332         intervalID;
38333
38334     function renew() {
38335         var expires = new Date();
38336         expires.setSeconds(expires.getSeconds() + 5);
38337         document.cookie = name + '=1; expires=' + expires.toUTCString();
38338     }
38339
38340     mutex.lock = function() {
38341         if (intervalID) return true;
38342         var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
38343         if (cookie) return false;
38344         renew();
38345         intervalID = window.setInterval(renew, 4000);
38346         return true;
38347     };
38348
38349     mutex.unlock = function() {
38350         if (!intervalID) return;
38351         document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
38352         clearInterval(intervalID);
38353         intervalID = null;
38354     };
38355
38356     mutex.locked = function() {
38357         return !!intervalID;
38358     };
38359
38360     return mutex;
38361 }
38362
38363 function utilSuggestNames(preset, suggestions) {
38364     preset = preset.id.split('/', 2);
38365     var k = preset[0],
38366         v = preset[1];
38367
38368     return function(value, callback) {
38369         var result = [];
38370         if (value && value.length > 2) {
38371             if (suggestions[k] && suggestions[k][v]) {
38372                 for (var sugg in suggestions[k][v]) {
38373                     var dist = utilEditDistance(value, sugg.substring(0, value.length));
38374                     if (dist < 3) {
38375                         result.push({
38376                             title: sugg,
38377                             value: sugg,
38378                             dist: dist
38379                         });
38380                     }
38381                 }
38382             }
38383             result.sort(function(a, b) {
38384                 return a.dist - b.dist;
38385             });
38386         }
38387         result = result.slice(0,3);
38388         callback(result);
38389     };
38390 }
38391
38392 function utilTriggerEvent(target, type) {
38393     target.each(function() {
38394         var evt = document.createEvent('HTMLEvents');
38395         evt.initEvent(type, true, true);
38396         this.dispatchEvent(evt);
38397     });
38398 }
38399
38400 function utilIdleWorker(tasks, processor, callback) {
38401     var processed = [];
38402     var currentPos = 0;
38403     var totalTasks = tasks.length;
38404
38405     function worker(deadline) {
38406         while (deadline.timeRemaining() > 0 && currentPos < totalTasks) {
38407             var result = processor(tasks[currentPos]);
38408
38409             // if falsy dont add to the processed list
38410             if (result) processed.push(result);
38411             currentPos++;
38412         }
38413
38414         // more tasks are left, we might need more idleCallbacks
38415         if (currentPos < totalTasks) {
38416             return window.requestIdleCallback(function(deadline) {worker(deadline);});
38417         }
38418
38419         // tasks are completed
38420         return callback(processed);
38421     }
38422
38423     window.requestIdleCallback(function(deadline) {worker(deadline);});
38424 }
38425
38426 // shim
38427 window.requestIdleCallback =
38428     window.requestIdleCallback ||
38429     function(cb) {
38430         var start = Date.now();
38431         return setTimeout(function() {
38432             cb({
38433                 didTimeout: false,
38434                 timeRemaining: function() {
38435                     return Math.max(0, 50 - (Date.now() - start));
38436                 }
38437             });
38438         }, 1);
38439     };
38440
38441 window.cancelIdleCallback =
38442     window.cancelIdleCallback ||
38443     function(id) {
38444         clearTimeout(id);
38445     };
38446
38447 // note the function should be of low priority
38448 // and should not be returning a value.
38449 function utilCallWhenIdle(func, timeout) {
38450     return function() {
38451         var args = arguments;
38452         var that = this;
38453         window.requestIdleCallback(function() {
38454             func.apply(that, args);
38455         }, {timeout: timeout});
38456     };
38457 }
38458
38459 function validationDeprecatedTag() {
38460
38461     var validation = function(changes) {
38462         var warnings = [];
38463         for (var i = 0; i < changes.created.length; i++) {
38464             var change = changes.created[i],
38465                 deprecatedTags = change.deprecatedTags();
38466
38467             if (!lodash.isEmpty(deprecatedTags)) {
38468                 var tags = utilTagText({ tags: deprecatedTags });
38469                 warnings.push({
38470                     id: 'deprecated_tags',
38471                     message: t('validations.deprecated_tags', { tags: tags }),
38472                     entity: change
38473                 });
38474             }
38475         }
38476
38477         return warnings;
38478     };
38479
38480
38481     return validation;
38482 }
38483
38484 function validationDisconnectedHighway() {
38485
38486
38487     function isDisconnectedHighway(entity, graph) {
38488         if (!entity.tags.highway) return false;
38489         if (entity.geometry(graph) !== 'line') return false;
38490
38491         return graph.childNodes(entity)
38492             .every(function(vertex) {
38493                 var parents = graph.parentWays(vertex);
38494                 if (parents.length === 1) {  // standalone vertex
38495                     return true;
38496                 } else {                     // shared vertex
38497                     return !vertex.tags.entrance &&
38498                         parents.filter(function(parent) {
38499                             return parent.tags.highway && parent !== entity;
38500                         }).length === 0;
38501                 }
38502             });
38503     }
38504
38505
38506     var validation = function(changes, graph) {
38507         var warnings = [];
38508         for (var i = 0; i < changes.created.length; i++) {
38509             var entity = changes.created[i];
38510
38511             if (isDisconnectedHighway(entity, graph)) {
38512                 warnings.push({
38513                     id: 'disconnected_highway',
38514                     message: t('validations.disconnected_highway'),
38515                     tooltip: t('validations.disconnected_highway_tooltip'),
38516                     entity: entity
38517                 });
38518             }
38519         }
38520
38521         return warnings;
38522     };
38523
38524
38525     return validation;
38526 }
38527
38528 function validationManyDeletions() {
38529     var threshold = 100;
38530
38531     var validation = function(changes) {
38532         var warnings = [];
38533         if (changes.deleted.length > threshold) {
38534             warnings.push({
38535                 id: 'many_deletions',
38536                 message: t('validations.many_deletions', { n: changes.deleted.length })
38537             });
38538         }
38539
38540         return warnings;
38541     };
38542
38543
38544     return validation;
38545 }
38546
38547 function validationMissingTag() {
38548
38549     // Slightly stricter check than Entity#isUsed (#3091)
38550     function hasTags(entity, graph) {
38551         return lodash.without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
38552             graph.parentRelations(entity).length > 0;
38553     }
38554
38555     var validation = function(changes, graph) {
38556         var types = ['point', 'line', 'area', 'relation'],
38557             warnings = [];
38558
38559         for (var i = 0; i < changes.created.length; i++) {
38560             var change = changes.created[i],
38561                 geometry = change.geometry(graph);
38562
38563             if (types.indexOf(geometry) !== -1 && !hasTags(change, graph)) {
38564                 warnings.push({
38565                     id: 'missing_tag',
38566                     message: t('validations.untagged_' + geometry),
38567                     tooltip: t('validations.untagged_' + geometry + '_tooltip'),
38568                     entity: change
38569                 });
38570             }
38571         }
38572
38573         return warnings;
38574     };
38575
38576
38577     return validation;
38578 }
38579
38580 function validationOldMultipolygon() {
38581
38582
38583     return function validation(changes, graph) {
38584         var warnings = [];
38585         for (var i = 0; i < changes.created.length; i++) {
38586             var entity = changes.created[i];
38587             var parent = osmIsSimpleMultipolygonOuterMember(entity, graph);
38588             if (parent) {
38589                 warnings.push({
38590                     id: 'old_multipolygon',
38591                     message: t('validations.old_multipolygon'),
38592                     tooltip: t('validations.old_multipolygon_tooltip'),
38593                     entity: parent
38594                 });
38595             }
38596         }
38597         return warnings;
38598     };
38599 }
38600
38601 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
38602 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
38603 function validationTagSuggestsArea() {
38604
38605     function tagSuggestsArea(tags) {
38606         if (lodash.isEmpty(tags)) return false;
38607
38608         var presence = ['landuse', 'amenities', 'tourism', 'shop'];
38609         for (var i = 0; i < presence.length; i++) {
38610             if (tags[presence[i]] !== undefined) {
38611                 return presence[i] + '=' + tags[presence[i]];
38612             }
38613         }
38614
38615         if (tags.building && tags.building === 'yes') return 'building=yes';
38616     }
38617
38618
38619     var validation = function(changes, graph) {
38620         var warnings = [];
38621         for (var i = 0; i < changes.created.length; i++) {
38622             var change = changes.created[i],
38623                 geometry = change.geometry(graph),
38624                 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
38625
38626             if (suggestion) {
38627                 warnings.push({
38628                     id: 'tag_suggests_area',
38629                     message: t('validations.tag_suggests_area', { tag: suggestion }),
38630                     entity: change
38631                 });
38632             }
38633         }
38634
38635         return warnings;
38636     };
38637
38638
38639     return validation;
38640 }
38641
38642
38643
38644 var Validations = Object.freeze({
38645         validationDeprecatedTag: validationDeprecatedTag,
38646         validationDisconnectedHighway: validationDisconnectedHighway,
38647         validationManyDeletions: validationManyDeletions,
38648         validationMissingTag: validationMissingTag,
38649         validationOldMultipolygon: validationOldMultipolygon,
38650         validationTagSuggestsArea: validationTagSuggestsArea
38651 });
38652
38653 /*
38654     iD.Difference represents the difference between two graphs.
38655     It knows how to calculate the set of entities that were
38656     created, modified, or deleted, and also contains the logic
38657     for recursively extending a difference to the complete set
38658     of entities that will require a redraw, taking into account
38659     child and parent relationships.
38660  */
38661 function coreDifference(base, head) {
38662     var changes = {},
38663         difference = {},
38664         length = 0;
38665
38666
38667     function changed(h, b) {
38668         return h !== b && !lodash.isEqual(lodash.omit(h, 'v'), lodash.omit(b, 'v'));
38669     }
38670
38671
38672     lodash.each(head.entities, function(h, id) {
38673         var b = base.entities[id];
38674         if (changed(h, b)) {
38675             changes[id] = {base: b, head: h};
38676             length++;
38677         }
38678     });
38679
38680
38681     lodash.each(base.entities, function(b, id) {
38682         var h = head.entities[id];
38683         if (!changes[id] && changed(h, b)) {
38684             changes[id] = {base: b, head: h};
38685             length++;
38686         }
38687     });
38688
38689
38690     function addParents(parents, result) {
38691         for (var i = 0; i < parents.length; i++) {
38692             var parent = parents[i];
38693
38694             if (parent.id in result)
38695                 continue;
38696
38697             result[parent.id] = parent;
38698             addParents(head.parentRelations(parent), result);
38699         }
38700     }
38701
38702
38703     difference.length = function() {
38704         return length;
38705     };
38706
38707
38708     difference.changes = function() {
38709         return changes;
38710     };
38711
38712
38713     difference.extantIDs = function() {
38714         var result = [];
38715         lodash.each(changes, function(change, id) {
38716             if (change.head) result.push(id);
38717         });
38718         return result;
38719     };
38720
38721
38722     difference.modified = function() {
38723         var result = [];
38724         lodash.each(changes, function(change) {
38725             if (change.base && change.head) result.push(change.head);
38726         });
38727         return result;
38728     };
38729
38730
38731     difference.created = function() {
38732         var result = [];
38733         lodash.each(changes, function(change) {
38734             if (!change.base && change.head) result.push(change.head);
38735         });
38736         return result;
38737     };
38738
38739
38740     difference.deleted = function() {
38741         var result = [];
38742         lodash.each(changes, function(change) {
38743             if (change.base && !change.head) result.push(change.base);
38744         });
38745         return result;
38746     };
38747
38748
38749     difference.summary = function() {
38750         var relevant = {};
38751
38752         function addEntity(entity, graph, changeType) {
38753             relevant[entity.id] = {
38754                 entity: entity,
38755                 graph: graph,
38756                 changeType: changeType
38757             };
38758         }
38759
38760         function addParents(entity) {
38761             var parents = head.parentWays(entity);
38762             for (var j = parents.length - 1; j >= 0; j--) {
38763                 var parent = parents[j];
38764                 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
38765             }
38766         }
38767
38768         lodash.each(changes, function(change) {
38769             if (change.head && change.head.geometry(head) !== 'vertex') {
38770                 addEntity(change.head, head, change.base ? 'modified' : 'created');
38771
38772             } else if (change.base && change.base.geometry(base) !== 'vertex') {
38773                 addEntity(change.base, base, 'deleted');
38774
38775             } else if (change.base && change.head) { // modified vertex
38776                 var moved    = !lodash.isEqual(change.base.loc,  change.head.loc),
38777                     retagged = !lodash.isEqual(change.base.tags, change.head.tags);
38778
38779                 if (moved) {
38780                     addParents(change.head);
38781                 }
38782
38783                 if (retagged || (moved && change.head.hasInterestingTags())) {
38784                     addEntity(change.head, head, 'modified');
38785                 }
38786
38787             } else if (change.head && change.head.hasInterestingTags()) { // created vertex
38788                 addEntity(change.head, head, 'created');
38789
38790             } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
38791                 addEntity(change.base, base, 'deleted');
38792             }
38793         });
38794
38795         return values(relevant);
38796     };
38797
38798
38799     difference.complete = function(extent$$1) {
38800         var result = {}, id, change;
38801
38802         for (id in changes) {
38803             change = changes[id];
38804
38805             var h = change.head,
38806                 b = change.base,
38807                 entity = h || b;
38808
38809             if (extent$$1 &&
38810                 (!h || !h.intersects(extent$$1, head)) &&
38811                 (!b || !b.intersects(extent$$1, base)))
38812                 continue;
38813
38814             result[id] = h;
38815
38816             if (entity.type === 'way') {
38817                 var nh = h ? h.nodes : [],
38818                     nb = b ? b.nodes : [],
38819                     diff, i;
38820
38821                 diff = lodash.difference(nh, nb);
38822                 for (i = 0; i < diff.length; i++) {
38823                     result[diff[i]] = head.hasEntity(diff[i]);
38824                 }
38825
38826                 diff = lodash.difference(nb, nh);
38827                 for (i = 0; i < diff.length; i++) {
38828                     result[diff[i]] = head.hasEntity(diff[i]);
38829                 }
38830             }
38831
38832             addParents(head.parentWays(entity), result);
38833             addParents(head.parentRelations(entity), result);
38834         }
38835
38836         return result;
38837     };
38838
38839
38840     return difference;
38841 }
38842
38843 function coreGraph$$1(other, mutable) {
38844     if (!(this instanceof coreGraph$$1)) return new coreGraph$$1(other, mutable);
38845
38846     if (other instanceof coreGraph$$1) {
38847         var base = other.base();
38848         this.entities = lodash.assign(Object.create(base.entities), other.entities);
38849         this._parentWays = lodash.assign(Object.create(base.parentWays), other._parentWays);
38850         this._parentRels = lodash.assign(Object.create(base.parentRels), other._parentRels);
38851
38852     } else {
38853         this.entities = Object.create({});
38854         this._parentWays = Object.create({});
38855         this._parentRels = Object.create({});
38856         this.rebase(other || [], [this]);
38857     }
38858
38859     this.transients = {};
38860     this._childNodes = {};
38861     this.frozen = !mutable;
38862 }
38863
38864
38865 coreGraph$$1.prototype = {
38866
38867     hasEntity: function(id) {
38868         return this.entities[id];
38869     },
38870
38871
38872     entity: function(id) {
38873         var entity = this.entities[id];
38874
38875         //https://github.com/openstreetmap/iD/issues/3973#issuecomment-307052376
38876         if (!entity) {
38877             entity = this.entities.__proto__[id];  // eslint-disable-line no-proto
38878         }
38879
38880         if (!entity) {
38881             throw new Error('entity ' + id + ' not found');
38882         }
38883         return entity;
38884     },
38885
38886
38887     transient: function(entity, key, fn) {
38888         var id = entity.id,
38889             transients = this.transients[id] ||
38890             (this.transients[id] = {});
38891
38892         if (transients[key] !== undefined) {
38893             return transients[key];
38894         }
38895
38896         transients[key] = fn.call(entity);
38897
38898         return transients[key];
38899     },
38900
38901
38902     parentWays: function(entity) {
38903         var parents = this._parentWays[entity.id],
38904             result = [];
38905
38906         if (parents) {
38907             for (var i = 0; i < parents.length; i++) {
38908                 result.push(this.entity(parents[i]));
38909             }
38910         }
38911         return result;
38912     },
38913
38914
38915     isPoi: function(entity) {
38916         var parentWays = this._parentWays[entity.id];
38917         return !parentWays || parentWays.length === 0;
38918     },
38919
38920
38921     isShared: function(entity) {
38922         var parentWays = this._parentWays[entity.id];
38923         return parentWays && parentWays.length > 1;
38924     },
38925
38926
38927     parentRelations: function(entity) {
38928         var parents = this._parentRels[entity.id],
38929             result = [];
38930
38931         if (parents) {
38932             for (var i = 0; i < parents.length; i++) {
38933                 result.push(this.entity(parents[i]));
38934             }
38935         }
38936         return result;
38937     },
38938
38939
38940     childNodes: function(entity) {
38941         if (this._childNodes[entity.id]) return this._childNodes[entity.id];
38942         if (!entity.nodes) return [];
38943
38944         var nodes = [];
38945         for (var i = 0; i < entity.nodes.length; i++) {
38946             nodes[i] = this.entity(entity.nodes[i]);
38947         }
38948
38949         if (debug) Object.freeze(nodes);
38950
38951         this._childNodes[entity.id] = nodes;
38952         return this._childNodes[entity.id];
38953     },
38954
38955
38956     base: function() {
38957         return {
38958             'entities': utilGetPrototypeOf(this.entities),
38959             'parentWays': utilGetPrototypeOf(this._parentWays),
38960             'parentRels': utilGetPrototypeOf(this._parentRels)
38961         };
38962     },
38963
38964
38965     // Unlike other graph methods, rebase mutates in place. This is because it
38966     // is used only during the history operation that merges newly downloaded
38967     // data into each state. To external consumers, it should appear as if the
38968     // graph always contained the newly downloaded data.
38969     rebase: function(entities, stack, force) {
38970         var base = this.base(),
38971             i, j, k, id;
38972
38973         for (i = 0; i < entities.length; i++) {
38974             var entity = entities[i];
38975
38976             if (!entity.visible || (!force && base.entities[entity.id]))
38977                 continue;
38978
38979             // Merging data into the base graph
38980             base.entities[entity.id] = entity;
38981             this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
38982
38983             // Restore provisionally-deleted nodes that are discovered to have an extant parent
38984             if (entity.type === 'way') {
38985                 for (j = 0; j < entity.nodes.length; j++) {
38986                     id = entity.nodes[j];
38987                     for (k = 1; k < stack.length; k++) {
38988                         var ents = stack[k].entities;
38989                         if (ents.hasOwnProperty(id) && ents[id] === undefined) {
38990                             delete ents[id];
38991                         }
38992                     }
38993                 }
38994             }
38995         }
38996
38997         for (i = 0; i < stack.length; i++) {
38998             stack[i]._updateRebased();
38999         }
39000     },
39001
39002
39003     _updateRebased: function() {
39004         var base = this.base(),
39005             i, k, child, id, keys;
39006
39007         keys = Object.keys(this._parentWays);
39008         for (i = 0; i < keys.length; i++) {
39009             child = keys[i];
39010             if (base.parentWays[child]) {
39011                 for (k = 0; k < base.parentWays[child].length; k++) {
39012                     id = base.parentWays[child][k];
39013                     if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentWays[child], id)) {
39014                         this._parentWays[child].push(id);
39015                     }
39016                 }
39017             }
39018         }
39019
39020         keys = Object.keys(this._parentRels);
39021         for (i = 0; i < keys.length; i++) {
39022             child = keys[i];
39023             if (base.parentRels[child]) {
39024                 for (k = 0; k < base.parentRels[child].length; k++) {
39025                     id = base.parentRels[child][k];
39026                     if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentRels[child], id)) {
39027                         this._parentRels[child].push(id);
39028                     }
39029                 }
39030             }
39031         }
39032
39033         this.transients = {};
39034
39035         // this._childNodes is not updated, under the assumption that
39036         // ways are always downloaded with their child nodes.
39037     },
39038
39039
39040     // Updates calculated properties (parentWays, parentRels) for the specified change
39041     _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
39042
39043         parentWays = parentWays || this._parentWays;
39044         parentRels = parentRels || this._parentRels;
39045
39046         var type = entity && entity.type || oldentity && oldentity.type,
39047             removed, added, ways, rels, i;
39048
39049
39050         if (type === 'way') {
39051
39052             // Update parentWays
39053             if (oldentity && entity) {
39054                 removed = lodash.difference(oldentity.nodes, entity.nodes);
39055                 added = lodash.difference(entity.nodes, oldentity.nodes);
39056             } else if (oldentity) {
39057                 removed = oldentity.nodes;
39058                 added = [];
39059             } else if (entity) {
39060                 removed = [];
39061                 added = entity.nodes;
39062             }
39063             for (i = 0; i < removed.length; i++) {
39064                 parentWays[removed[i]] = lodash.without(parentWays[removed[i]], oldentity.id);
39065             }
39066             for (i = 0; i < added.length; i++) {
39067                 ways = lodash.without(parentWays[added[i]], entity.id);
39068                 ways.push(entity.id);
39069                 parentWays[added[i]] = ways;
39070             }
39071
39072         } else if (type === 'relation') {
39073
39074             // Update parentRels
39075             if (oldentity && entity) {
39076                 removed = lodash.difference(oldentity.members, entity.members);
39077                 added = lodash.difference(entity.members, oldentity);
39078             } else if (oldentity) {
39079                 removed = oldentity.members;
39080                 added = [];
39081             } else if (entity) {
39082                 removed = [];
39083                 added = entity.members;
39084             }
39085             for (i = 0; i < removed.length; i++) {
39086                 parentRels[removed[i].id] = lodash.without(parentRels[removed[i].id], oldentity.id);
39087             }
39088             for (i = 0; i < added.length; i++) {
39089                 rels = lodash.without(parentRels[added[i].id], entity.id);
39090                 rels.push(entity.id);
39091                 parentRels[added[i].id] = rels;
39092             }
39093         }
39094     },
39095
39096
39097     replace: function(entity) {
39098         if (this.entities[entity.id] === entity)
39099             return this;
39100
39101         return this.update(function() {
39102             this._updateCalculated(this.entities[entity.id], entity);
39103             this.entities[entity.id] = entity;
39104         });
39105     },
39106
39107
39108     remove: function(entity) {
39109         return this.update(function() {
39110             this._updateCalculated(entity, undefined);
39111             this.entities[entity.id] = undefined;
39112         });
39113     },
39114
39115
39116     revert: function(id) {
39117         var baseEntity = this.base().entities[id],
39118             headEntity = this.entities[id];
39119
39120         if (headEntity === baseEntity)
39121             return this;
39122
39123         return this.update(function() {
39124             this._updateCalculated(headEntity, baseEntity);
39125             delete this.entities[id];
39126         });
39127     },
39128
39129
39130     update: function() {
39131         var graph = this.frozen ? coreGraph$$1(this, true) : this;
39132
39133         for (var i = 0; i < arguments.length; i++) {
39134             arguments[i].call(graph, graph);
39135         }
39136
39137         if (this.frozen) graph.frozen = true;
39138
39139         return graph;
39140     },
39141
39142
39143     // Obliterates any existing entities
39144     load: function(entities) {
39145         var base = this.base();
39146         this.entities = Object.create(base.entities);
39147
39148         for (var i in entities) {
39149             this.entities[i] = entities[i];
39150             this._updateCalculated(base.entities[i], this.entities[i]);
39151         }
39152
39153         return this;
39154     }
39155 };
39156
39157 var index$10 = partialSort;
39158
39159 // Floyd-Rivest selection algorithm:
39160 // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right];
39161 // The k-th element will have the (k - left + 1)th smallest value in [left, right]
39162
39163 function partialSort(arr, k, left, right, compare) {
39164     left = left || 0;
39165     right = right || (arr.length - 1);
39166     compare = compare || defaultCompare;
39167
39168     while (right > left) {
39169         if (right - left > 600) {
39170             var n = right - left + 1;
39171             var m = k - left + 1;
39172             var z = Math.log(n);
39173             var s = 0.5 * Math.exp(2 * z / 3);
39174             var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
39175             var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
39176             var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
39177             partialSort(arr, k, newLeft, newRight, compare);
39178         }
39179
39180         var t = arr[k];
39181         var i = left;
39182         var j = right;
39183
39184         swap(arr, left, k);
39185         if (compare(arr[right], t) > 0) swap(arr, left, right);
39186
39187         while (i < j) {
39188             swap(arr, i, j);
39189             i++;
39190             j--;
39191             while (compare(arr[i], t) < 0) i++;
39192             while (compare(arr[j], t) > 0) j--;
39193         }
39194
39195         if (compare(arr[left], t) === 0) swap(arr, left, j);
39196         else {
39197             j++;
39198             swap(arr, j, right);
39199         }
39200
39201         if (j <= k) left = j + 1;
39202         if (k <= j) right = j - 1;
39203     }
39204 }
39205
39206 function swap(arr, i, j) {
39207     var tmp = arr[i];
39208     arr[i] = arr[j];
39209     arr[j] = tmp;
39210 }
39211
39212 function defaultCompare(a, b) {
39213     return a < b ? -1 : a > b ? 1 : 0;
39214 }
39215
39216 var index$9 = rbush;
39217
39218
39219
39220 function rbush(maxEntries, format) {
39221     if (!(this instanceof rbush)) return new rbush(maxEntries, format);
39222
39223     // max entries in a node is 9 by default; min node fill is 40% for best performance
39224     this._maxEntries = Math.max(4, maxEntries || 9);
39225     this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
39226
39227     if (format) {
39228         this._initFormat(format);
39229     }
39230
39231     this.clear();
39232 }
39233
39234 rbush.prototype = {
39235
39236     all: function () {
39237         return this._all(this.data, []);
39238     },
39239
39240     search: function (bbox) {
39241
39242         var node = this.data,
39243             result = [],
39244             toBBox = this.toBBox;
39245
39246         if (!intersects$1(bbox, node)) return result;
39247
39248         var nodesToSearch = [],
39249             i, len, child, childBBox;
39250
39251         while (node) {
39252             for (i = 0, len = node.children.length; i < len; i++) {
39253
39254                 child = node.children[i];
39255                 childBBox = node.leaf ? toBBox(child) : child;
39256
39257                 if (intersects$1(bbox, childBBox)) {
39258                     if (node.leaf) result.push(child);
39259                     else if (contains$2(bbox, childBBox)) this._all(child, result);
39260                     else nodesToSearch.push(child);
39261                 }
39262             }
39263             node = nodesToSearch.pop();
39264         }
39265
39266         return result;
39267     },
39268
39269     collides: function (bbox) {
39270
39271         var node = this.data,
39272             toBBox = this.toBBox;
39273
39274         if (!intersects$1(bbox, node)) return false;
39275
39276         var nodesToSearch = [],
39277             i, len, child, childBBox;
39278
39279         while (node) {
39280             for (i = 0, len = node.children.length; i < len; i++) {
39281
39282                 child = node.children[i];
39283                 childBBox = node.leaf ? toBBox(child) : child;
39284
39285                 if (intersects$1(bbox, childBBox)) {
39286                     if (node.leaf || contains$2(bbox, childBBox)) return true;
39287                     nodesToSearch.push(child);
39288                 }
39289             }
39290             node = nodesToSearch.pop();
39291         }
39292
39293         return false;
39294     },
39295
39296     load: function (data) {
39297         if (!(data && data.length)) return this;
39298
39299         if (data.length < this._minEntries) {
39300             for (var i = 0, len = data.length; i < len; i++) {
39301                 this.insert(data[i]);
39302             }
39303             return this;
39304         }
39305
39306         // recursively build the tree with the given data from stratch using OMT algorithm
39307         var node = this._build(data.slice(), 0, data.length - 1, 0);
39308
39309         if (!this.data.children.length) {
39310             // save as is if tree is empty
39311             this.data = node;
39312
39313         } else if (this.data.height === node.height) {
39314             // split root if trees have the same height
39315             this._splitRoot(this.data, node);
39316
39317         } else {
39318             if (this.data.height < node.height) {
39319                 // swap trees if inserted one is bigger
39320                 var tmpNode = this.data;
39321                 this.data = node;
39322                 node = tmpNode;
39323             }
39324
39325             // insert the small tree into the large tree at appropriate level
39326             this._insert(node, this.data.height - node.height - 1, true);
39327         }
39328
39329         return this;
39330     },
39331
39332     insert: function (item) {
39333         if (item) this._insert(item, this.data.height - 1);
39334         return this;
39335     },
39336
39337     clear: function () {
39338         this.data = createNode([]);
39339         return this;
39340     },
39341
39342     remove: function (item, equalsFn) {
39343         if (!item) return this;
39344
39345         var node = this.data,
39346             bbox = this.toBBox(item),
39347             path = [],
39348             indexes = [],
39349             i, parent, index, goingUp;
39350
39351         // depth-first iterative tree traversal
39352         while (node || path.length) {
39353
39354             if (!node) { // go up
39355                 node = path.pop();
39356                 parent = path[path.length - 1];
39357                 i = indexes.pop();
39358                 goingUp = true;
39359             }
39360
39361             if (node.leaf) { // check current node
39362                 index = findItem(item, node.children, equalsFn);
39363
39364                 if (index !== -1) {
39365                     // item found, remove the item and condense tree upwards
39366                     node.children.splice(index, 1);
39367                     path.push(node);
39368                     this._condense(path);
39369                     return this;
39370                 }
39371             }
39372
39373             if (!goingUp && !node.leaf && contains$2(node, bbox)) { // go down
39374                 path.push(node);
39375                 indexes.push(i);
39376                 i = 0;
39377                 parent = node;
39378                 node = node.children[0];
39379
39380             } else if (parent) { // go right
39381                 i++;
39382                 node = parent.children[i];
39383                 goingUp = false;
39384
39385             } else node = null; // nothing found
39386         }
39387
39388         return this;
39389     },
39390
39391     toBBox: function (item) { return item; },
39392
39393     compareMinX: compareNodeMinX,
39394     compareMinY: compareNodeMinY,
39395
39396     toJSON: function () { return this.data; },
39397
39398     fromJSON: function (data) {
39399         this.data = data;
39400         return this;
39401     },
39402
39403     _all: function (node, result) {
39404         var nodesToSearch = [];
39405         while (node) {
39406             if (node.leaf) result.push.apply(result, node.children);
39407             else nodesToSearch.push.apply(nodesToSearch, node.children);
39408
39409             node = nodesToSearch.pop();
39410         }
39411         return result;
39412     },
39413
39414     _build: function (items, left, right, height) {
39415
39416         var N = right - left + 1,
39417             M = this._maxEntries,
39418             node;
39419
39420         if (N <= M) {
39421             // reached leaf level; return leaf
39422             node = createNode(items.slice(left, right + 1));
39423             calcBBox(node, this.toBBox);
39424             return node;
39425         }
39426
39427         if (!height) {
39428             // target height of the bulk-loaded tree
39429             height = Math.ceil(Math.log(N) / Math.log(M));
39430
39431             // target number of root entries to maximize storage utilization
39432             M = Math.ceil(N / Math.pow(M, height - 1));
39433         }
39434
39435         node = createNode([]);
39436         node.leaf = false;
39437         node.height = height;
39438
39439         // split the items into M mostly square tiles
39440
39441         var N2 = Math.ceil(N / M),
39442             N1 = N2 * Math.ceil(Math.sqrt(M)),
39443             i, j, right2, right3;
39444
39445         multiSelect(items, left, right, N1, this.compareMinX);
39446
39447         for (i = left; i <= right; i += N1) {
39448
39449             right2 = Math.min(i + N1 - 1, right);
39450
39451             multiSelect(items, i, right2, N2, this.compareMinY);
39452
39453             for (j = i; j <= right2; j += N2) {
39454
39455                 right3 = Math.min(j + N2 - 1, right2);
39456
39457                 // pack each entry recursively
39458                 node.children.push(this._build(items, j, right3, height - 1));
39459             }
39460         }
39461
39462         calcBBox(node, this.toBBox);
39463
39464         return node;
39465     },
39466
39467     _chooseSubtree: function (bbox, node, level, path) {
39468
39469         var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
39470
39471         while (true) {
39472             path.push(node);
39473
39474             if (node.leaf || path.length - 1 === level) break;
39475
39476             minArea = minEnlargement = Infinity;
39477
39478             for (i = 0, len = node.children.length; i < len; i++) {
39479                 child = node.children[i];
39480                 area = bboxArea(child);
39481                 enlargement = enlargedArea(bbox, child) - area;
39482
39483                 // choose entry with the least area enlargement
39484                 if (enlargement < minEnlargement) {
39485                     minEnlargement = enlargement;
39486                     minArea = area < minArea ? area : minArea;
39487                     targetNode = child;
39488
39489                 } else if (enlargement === minEnlargement) {
39490                     // otherwise choose one with the smallest area
39491                     if (area < minArea) {
39492                         minArea = area;
39493                         targetNode = child;
39494                     }
39495                 }
39496             }
39497
39498             node = targetNode || node.children[0];
39499         }
39500
39501         return node;
39502     },
39503
39504     _insert: function (item, level, isNode) {
39505
39506         var toBBox = this.toBBox,
39507             bbox = isNode ? item : toBBox(item),
39508             insertPath = [];
39509
39510         // find the best node for accommodating the item, saving all nodes along the path too
39511         var node = this._chooseSubtree(bbox, this.data, level, insertPath);
39512
39513         // put the item into the node
39514         node.children.push(item);
39515         extend$1(node, bbox);
39516
39517         // split on node overflow; propagate upwards if necessary
39518         while (level >= 0) {
39519             if (insertPath[level].children.length > this._maxEntries) {
39520                 this._split(insertPath, level);
39521                 level--;
39522             } else break;
39523         }
39524
39525         // adjust bboxes along the insertion path
39526         this._adjustParentBBoxes(bbox, insertPath, level);
39527     },
39528
39529     // split overflowed node into two
39530     _split: function (insertPath, level) {
39531
39532         var node = insertPath[level],
39533             M = node.children.length,
39534             m = this._minEntries;
39535
39536         this._chooseSplitAxis(node, m, M);
39537
39538         var splitIndex = this._chooseSplitIndex(node, m, M);
39539
39540         var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
39541         newNode.height = node.height;
39542         newNode.leaf = node.leaf;
39543
39544         calcBBox(node, this.toBBox);
39545         calcBBox(newNode, this.toBBox);
39546
39547         if (level) insertPath[level - 1].children.push(newNode);
39548         else this._splitRoot(node, newNode);
39549     },
39550
39551     _splitRoot: function (node, newNode) {
39552         // split root node
39553         this.data = createNode([node, newNode]);
39554         this.data.height = node.height + 1;
39555         this.data.leaf = false;
39556         calcBBox(this.data, this.toBBox);
39557     },
39558
39559     _chooseSplitIndex: function (node, m, M) {
39560
39561         var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
39562
39563         minOverlap = minArea = Infinity;
39564
39565         for (i = m; i <= M - m; i++) {
39566             bbox1 = distBBox(node, 0, i, this.toBBox);
39567             bbox2 = distBBox(node, i, M, this.toBBox);
39568
39569             overlap = intersectionArea(bbox1, bbox2);
39570             area = bboxArea(bbox1) + bboxArea(bbox2);
39571
39572             // choose distribution with minimum overlap
39573             if (overlap < minOverlap) {
39574                 minOverlap = overlap;
39575                 index = i;
39576
39577                 minArea = area < minArea ? area : minArea;
39578
39579             } else if (overlap === minOverlap) {
39580                 // otherwise choose distribution with minimum area
39581                 if (area < minArea) {
39582                     minArea = area;
39583                     index = i;
39584                 }
39585             }
39586         }
39587
39588         return index;
39589     },
39590
39591     // sorts node children by the best axis for split
39592     _chooseSplitAxis: function (node, m, M) {
39593
39594         var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
39595             compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
39596             xMargin = this._allDistMargin(node, m, M, compareMinX),
39597             yMargin = this._allDistMargin(node, m, M, compareMinY);
39598
39599         // if total distributions margin value is minimal for x, sort by minX,
39600         // otherwise it's already sorted by minY
39601         if (xMargin < yMargin) node.children.sort(compareMinX);
39602     },
39603
39604     // total margin of all possible split distributions where each node is at least m full
39605     _allDistMargin: function (node, m, M, compare) {
39606
39607         node.children.sort(compare);
39608
39609         var toBBox = this.toBBox,
39610             leftBBox = distBBox(node, 0, m, toBBox),
39611             rightBBox = distBBox(node, M - m, M, toBBox),
39612             margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
39613             i, child;
39614
39615         for (i = m; i < M - m; i++) {
39616             child = node.children[i];
39617             extend$1(leftBBox, node.leaf ? toBBox(child) : child);
39618             margin += bboxMargin(leftBBox);
39619         }
39620
39621         for (i = M - m - 1; i >= m; i--) {
39622             child = node.children[i];
39623             extend$1(rightBBox, node.leaf ? toBBox(child) : child);
39624             margin += bboxMargin(rightBBox);
39625         }
39626
39627         return margin;
39628     },
39629
39630     _adjustParentBBoxes: function (bbox, path, level) {
39631         // adjust bboxes along the given tree path
39632         for (var i = level; i >= 0; i--) {
39633             extend$1(path[i], bbox);
39634         }
39635     },
39636
39637     _condense: function (path) {
39638         // go through the path, removing empty nodes and updating bboxes
39639         for (var i = path.length - 1, siblings; i >= 0; i--) {
39640             if (path[i].children.length === 0) {
39641                 if (i > 0) {
39642                     siblings = path[i - 1].children;
39643                     siblings.splice(siblings.indexOf(path[i]), 1);
39644
39645                 } else this.clear();
39646
39647             } else calcBBox(path[i], this.toBBox);
39648         }
39649     },
39650
39651     _initFormat: function (format) {
39652         // data format (minX, minY, maxX, maxY accessors)
39653
39654         // uses eval-type function compilation instead of just accepting a toBBox function
39655         // because the algorithms are very sensitive to sorting functions performance,
39656         // so they should be dead simple and without inner calls
39657
39658         var compareArr = ['return a', ' - b', ';'];
39659
39660         this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
39661         this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
39662
39663         this.toBBox = new Function('a',
39664             'return {minX: a' + format[0] +
39665             ', minY: a' + format[1] +
39666             ', maxX: a' + format[2] +
39667             ', maxY: a' + format[3] + '};');
39668     }
39669 };
39670
39671 function findItem(item, items, equalsFn) {
39672     if (!equalsFn) return items.indexOf(item);
39673
39674     for (var i = 0; i < items.length; i++) {
39675         if (equalsFn(item, items[i])) return i;
39676     }
39677     return -1;
39678 }
39679
39680 // calculate node's bbox from bboxes of its children
39681 function calcBBox(node, toBBox) {
39682     distBBox(node, 0, node.children.length, toBBox, node);
39683 }
39684
39685 // min bounding rectangle of node children from k to p-1
39686 function distBBox(node, k, p, toBBox, destNode) {
39687     if (!destNode) destNode = createNode(null);
39688     destNode.minX = Infinity;
39689     destNode.minY = Infinity;
39690     destNode.maxX = -Infinity;
39691     destNode.maxY = -Infinity;
39692
39693     for (var i = k, child; i < p; i++) {
39694         child = node.children[i];
39695         extend$1(destNode, node.leaf ? toBBox(child) : child);
39696     }
39697
39698     return destNode;
39699 }
39700
39701 function extend$1(a, b) {
39702     a.minX = Math.min(a.minX, b.minX);
39703     a.minY = Math.min(a.minY, b.minY);
39704     a.maxX = Math.max(a.maxX, b.maxX);
39705     a.maxY = Math.max(a.maxY, b.maxY);
39706     return a;
39707 }
39708
39709 function compareNodeMinX(a, b) { return a.minX - b.minX; }
39710 function compareNodeMinY(a, b) { return a.minY - b.minY; }
39711
39712 function bboxArea(a)   { return (a.maxX - a.minX) * (a.maxY - a.minY); }
39713 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
39714
39715 function enlargedArea(a, b) {
39716     return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
39717            (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
39718 }
39719
39720 function intersectionArea(a, b) {
39721     var minX = Math.max(a.minX, b.minX),
39722         minY = Math.max(a.minY, b.minY),
39723         maxX = Math.min(a.maxX, b.maxX),
39724         maxY = Math.min(a.maxY, b.maxY);
39725
39726     return Math.max(0, maxX - minX) *
39727            Math.max(0, maxY - minY);
39728 }
39729
39730 function contains$2(a, b) {
39731     return a.minX <= b.minX &&
39732            a.minY <= b.minY &&
39733            b.maxX <= a.maxX &&
39734            b.maxY <= a.maxY;
39735 }
39736
39737 function intersects$1(a, b) {
39738     return b.minX <= a.maxX &&
39739            b.minY <= a.maxY &&
39740            b.maxX >= a.minX &&
39741            b.maxY >= a.minY;
39742 }
39743
39744 function createNode(children) {
39745     return {
39746         children: children,
39747         height: 1,
39748         leaf: true,
39749         minX: Infinity,
39750         minY: Infinity,
39751         maxX: -Infinity,
39752         maxY: -Infinity
39753     };
39754 }
39755
39756 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
39757 // combines selection algorithm with binary divide & conquer approach
39758
39759 function multiSelect(arr, left, right, n, compare) {
39760     var stack = [left, right],
39761         mid;
39762
39763     while (stack.length) {
39764         right = stack.pop();
39765         left = stack.pop();
39766
39767         if (right - left <= n) continue;
39768
39769         mid = left + Math.ceil((right - left) / n / 2) * n;
39770         index$10(arr, mid, left, right, compare);
39771
39772         stack.push(left, mid, mid, right);
39773     }
39774 }
39775
39776 function coreTree(head) {
39777     var rtree = index$9(),
39778         bboxes = {},
39779         tree = {};
39780
39781
39782     function entityBBox(entity) {
39783         var bbox = entity.extent(head).bbox();
39784         bbox.id = entity.id;
39785         bboxes[entity.id] = bbox;
39786         return bbox;
39787     }
39788
39789
39790     function updateParents(entity, insertions, memo) {
39791         head.parentWays(entity).forEach(function(way) {
39792             if (bboxes[way.id]) {
39793                 rtree.remove(bboxes[way.id]);
39794                 insertions[way.id] = way;
39795             }
39796             updateParents(way, insertions, memo);
39797         });
39798
39799         head.parentRelations(entity).forEach(function(relation) {
39800             if (memo[entity.id]) return;
39801             memo[entity.id] = true;
39802             if (bboxes[relation.id]) {
39803                 rtree.remove(bboxes[relation.id]);
39804                 insertions[relation.id] = relation;
39805             }
39806             updateParents(relation, insertions, memo);
39807         });
39808     }
39809
39810
39811     tree.rebase = function(entities, force) {
39812         var insertions = {};
39813
39814         for (var i = 0; i < entities.length; i++) {
39815             var entity = entities[i];
39816
39817             if (!entity.visible)
39818                 continue;
39819
39820             if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
39821                 if (!force) {
39822                     continue;
39823                 } else if (bboxes[entity.id]) {
39824                     rtree.remove(bboxes[entity.id]);
39825                 }
39826             }
39827
39828             insertions[entity.id] = entity;
39829             updateParents(entity, insertions, {});
39830         }
39831
39832         rtree.load(lodash.map(insertions, entityBBox));
39833
39834         return tree;
39835     };
39836
39837
39838     tree.intersects = function(extent, graph) {
39839         if (graph !== head) {
39840             var diff = coreDifference(head, graph),
39841                 insertions = {};
39842
39843             head = graph;
39844
39845             diff.deleted().forEach(function(entity) {
39846                 rtree.remove(bboxes[entity.id]);
39847                 delete bboxes[entity.id];
39848             });
39849
39850             diff.modified().forEach(function(entity) {
39851                 rtree.remove(bboxes[entity.id]);
39852                 insertions[entity.id] = entity;
39853                 updateParents(entity, insertions, {});
39854             });
39855
39856             diff.created().forEach(function(entity) {
39857                 insertions[entity.id] = entity;
39858             });
39859
39860             rtree.load(lodash.map(insertions, entityBBox));
39861         }
39862
39863         return rtree.search(extent.bbox()).map(function(bbox) {
39864             return head.entity(bbox.id);
39865         });
39866     };
39867
39868
39869     return tree;
39870 }
39871
39872 /*
39873  * This code is licensed under the MIT license.
39874  *
39875  * Copyright © 2013, iD authors.
39876  *
39877  * Portions copyright © 2011, Keith Cirkel
39878  * See https://github.com/keithamus/jwerty
39879  *
39880  */
39881 function d3keybinding(namespace$$1) {
39882     var bindings = [];
39883
39884
39885     function testBindings(isCapturing) {
39886         var didMatch = false,
39887             i, binding;
39888
39889         // Most key shortcuts will accept either lower or uppercase ('h' or 'H'),
39890         // so we don't strictly match on the shift key, but we prioritize
39891         // shifted bindings first, and fallback to unshifted only if no match.
39892         // (This lets us differentiate between '←'/'⇧←' or '⌘Z'/'⌘⇧Z')
39893
39894         // priority match shifted bindings first
39895         for (i = 0; i < bindings.length; i++) {
39896             binding = bindings[i];
39897             if (!binding.event.modifiers.shiftKey) continue;  // no shift
39898             if (!!binding.capture !== isCapturing) continue;
39899             if (matches(binding, true)) {
39900                 binding.callback();
39901                 didMatch = true;
39902             }
39903         }
39904
39905         // then unshifted bindings
39906         if (didMatch) return;
39907         for (i = 0; i < bindings.length; i++) {
39908             binding = bindings[i];
39909             if (binding.event.modifiers.shiftKey) continue;   // shift
39910             if (!!binding.capture !== isCapturing) continue;
39911             if (matches(binding, false)) {
39912                 binding.callback();
39913             }
39914         }
39915
39916
39917         function matches(binding, testShift) {
39918             var event$$1 = event;
39919             if (event$$1.key !== undefined) {
39920                 if (binding.event.key === undefined) {
39921                     return false;
39922                 } else if (lodash.isArray(binding.event.key)) {
39923                     if (binding.event.key.map(function(s) { return s.toLowerCase(); }).indexOf(event$$1.key.toLowerCase()) === -1)
39924                         return false;
39925                 } else {
39926                     if (event$$1.key.toLowerCase() !== binding.event.key.toLowerCase())
39927                         return false;
39928                 }
39929             } else {
39930                 // check keycodes if browser doesn't support KeyboardEvent.key
39931                 if (event$$1.keyCode !== binding.event.keyCode)
39932                     return false;
39933             }
39934
39935             // test modifier keys
39936             if (!(event$$1.ctrlKey && event$$1.altKey)) {  // if both are set, assume AltGr and skip it - #4096
39937                 if (event$$1.ctrlKey !== binding.event.modifiers.ctrlKey) return false;
39938                 if (event$$1.altKey !== binding.event.modifiers.altKey) return false;
39939             }
39940             if (event$$1.metaKey !== binding.event.modifiers.metaKey) return false;
39941             if (testShift && event$$1.shiftKey !== binding.event.modifiers.shiftKey) return false;
39942
39943             return true;
39944         }
39945     }
39946
39947
39948     function capture() {
39949         testBindings(true);
39950     }
39951
39952
39953     function bubble() {
39954         var tagName = select(event.target).node().tagName;
39955         if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
39956             return;
39957         }
39958         testBindings(false);
39959     }
39960
39961
39962     function keybinding(selection$$1) {
39963         selection$$1 = selection$$1 || select(document);
39964         selection$$1.on('keydown.capture' + namespace$$1, capture, true);
39965         selection$$1.on('keydown.bubble' + namespace$$1, bubble, false);
39966         return keybinding;
39967     }
39968
39969
39970     keybinding.off = function(selection$$1) {
39971         bindings = [];
39972         selection$$1 = selection$$1 || select(document);
39973         selection$$1.on('keydown.capture' + namespace$$1, null);
39974         selection$$1.on('keydown.bubble' + namespace$$1, null);
39975         return keybinding;
39976     };
39977
39978
39979     keybinding.on = function(codes, callback, capture) {
39980         var arr = [].concat(codes);
39981         for (var i = 0; i < arr.length; i++) {
39982             var code = arr[i];
39983             var binding = {
39984                 event: {
39985                     key: undefined,
39986                     keyCode: 0, // only for browsers that don't support KeyboardEvent.key
39987                     modifiers: {
39988                         shiftKey: false,
39989                         ctrlKey: false,
39990                         altKey: false,
39991                         metaKey: false
39992                     }
39993                 },
39994                 capture: capture,
39995                 callback: callback
39996             };
39997
39998             code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
39999
40000             for (var j = 0; j < code.length; j++) {
40001                 // Normalise matching errors
40002                 if (code[j] === '++') code[j] = '+';
40003
40004                 if (code[j] in d3keybinding.modifierCodes) {
40005                     binding.event.modifiers[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
40006                 } else {
40007                     binding.event.key = d3keybinding.keys[code[j]] || code[j];
40008                     if (code[j] in d3keybinding.keyCodes) {
40009                         binding.event.keyCode = d3keybinding.keyCodes[code[j]];
40010                     }
40011                 }
40012             }
40013
40014             bindings.push(binding);
40015         }
40016
40017         return keybinding;
40018     };
40019
40020     return keybinding;
40021 }
40022
40023
40024 d3keybinding.modifierCodes = {
40025     // Shift key, ⇧
40026     '⇧': 16, shift: 16,
40027     // CTRL key, on Mac: ⌃
40028     '⌃': 17, ctrl: 17,
40029     // ALT key, on Mac: ⌥ (Alt)
40030     '⌥': 18, alt: 18, option: 18,
40031     // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
40032     '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
40033 };
40034
40035 d3keybinding.modifierProperties = {
40036     16: 'shiftKey',
40037     17: 'ctrlKey',
40038     18: 'altKey',
40039     91: 'metaKey'
40040 };
40041
40042 d3keybinding.keys = {
40043     // Backspace key, on Mac: ⌫ (Backspace)
40044     '⌫': 'Backspace', backspace: 'Backspace',
40045     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
40046     '⇥': 'Tab', '⇆': 'Tab', tab: 'Tab',
40047     // Return key, ↩
40048     '↩': 'Enter', 'return': 'Enter', enter: 'Enter', '⌅': 'Enter',
40049     // Pause/Break key
40050     'pause': 'Pause', 'pause-break': 'Pause',
40051     // Caps Lock key, ⇪
40052     '⇪': 'CapsLock', caps: 'CapsLock', 'caps-lock': 'CapsLock',
40053     // Escape key, on Mac: ⎋, on Windows: Esc
40054     '⎋': ['Escape', 'Esc'], escape: ['Escape', 'Esc'], esc: ['Escape', 'Esc'],
40055     // Space key
40056     space: [' ', 'Spacebar'],
40057     // Page-Up key, or pgup, on Mac: ↖
40058     '↖': 'PageUp', pgup: 'PageUp', 'page-up': 'PageUp',
40059     // Page-Down key, or pgdown, on Mac: ↘
40060     '↘': 'PageDown', pgdown: 'PageDown', 'page-down': 'PageDown',
40061     // END key, on Mac: ⇟
40062     '⇟': 'End', end: 'End',
40063     // HOME key, on Mac: ⇞
40064     '⇞': 'Home', home: 'Home',
40065     // Insert key, or ins
40066     ins: 'Insert', insert: 'Insert',
40067     // Delete key, on Mac: ⌦ (Delete)
40068     '⌦': ['Delete', 'Del'], del: ['Delete', 'Del'], 'delete': ['Delete', 'Del'],
40069     // Left Arrow Key, or ←
40070     '←': ['ArrowLeft', 'Left'], left: ['ArrowLeft', 'Left'], 'arrow-left': ['ArrowLeft', 'Left'],
40071     // Up Arrow Key, or ↑
40072     '↑': ['ArrowUp', 'Up'], up: ['ArrowUp', 'Up'], 'arrow-up': ['ArrowUp', 'Up'],
40073     // Right Arrow Key, or →
40074     '→': ['ArrowRight', 'Right'], right: ['ArrowRight', 'Right'], 'arrow-right': ['ArrowRight', 'Right'],
40075     // Up Arrow Key, or ↓
40076     '↓': ['ArrowDown', 'Down'], down: ['ArrowDown', 'Down'], 'arrow-down': ['ArrowDown', 'Down'],
40077     // odities, stuff for backward compatibility (browsers and code):
40078     // Num-Multiply, or *
40079     '*': ['*', 'Multiply'], star: ['*', 'Multiply'], asterisk: ['*', 'Multiply'], multiply: ['*', 'Multiply'],
40080     // Num-Plus or +
40081     '+': ['+', 'Add'], 'plus': ['+', 'Add'],
40082     // Num-Subtract, or -
40083     '-': ['-', 'Subtract'], subtract: ['-', 'Subtract'], 'dash': ['-', 'Subtract'],
40084     // Semicolon
40085     semicolon: ';',
40086     // = or equals
40087     equals: '=',
40088     // Comma, or ,
40089     comma: ',',
40090     // Period, or ., or full-stop
40091     period: '.', 'full-stop': '.',
40092     // Slash, or /, or forward-slash
40093     slash: '/', 'forward-slash': '/',
40094     // Tick, or `, or back-quote
40095     tick: '`', 'back-quote': '`',
40096     // Open bracket, or [
40097     'open-bracket': '[',
40098     // Back slash, or \
40099     'back-slash': '\\',
40100     // Close backet, or ]
40101     'close-bracket': ']',
40102     // Apostrophe, or Quote, or '
40103     quote: '\'', apostrophe: '\'',
40104     // NUMPAD 0-9
40105     'num-0': '0',
40106     'num-1': '1',
40107     'num-2': '2',
40108     'num-3': '3',
40109     'num-4': '4',
40110     'num-5': '5',
40111     'num-6': '6',
40112     'num-7': '7',
40113     'num-8': '8',
40114     'num-9': '9',
40115     // F1-F25
40116     f1: 'F1',
40117     f2: 'F2',
40118     f3: 'F3',
40119     f4: 'F4',
40120     f5: 'F5',
40121     f6: 'F6',
40122     f7: 'F7',
40123     f8: 'F8',
40124     f9: 'F9',
40125     f10: 'F10',
40126     f11: 'F11',
40127     f12: 'F12',
40128     f13: 'F13',
40129     f14: 'F14',
40130     f15: 'F15',
40131     f16: 'F16',
40132     f17: 'F17',
40133     f18: 'F18',
40134     f19: 'F19',
40135     f20: 'F20',
40136     f21: 'F21',
40137     f22: 'F22',
40138     f23: 'F23',
40139     f24: 'F24',
40140     f25: 'F25'
40141 };
40142
40143 d3keybinding.keyCodes = {
40144     // Backspace key, on Mac: ⌫ (Backspace)
40145     '⌫': 8, backspace: 8,
40146     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
40147     '⇥': 9, '⇆': 9, tab: 9,
40148     // Return key, ↩
40149     '↩': 13, 'return': 13, enter: 13, '⌅': 13,
40150     // Pause/Break key
40151     'pause': 19, 'pause-break': 19,
40152     // Caps Lock key, ⇪
40153     '⇪': 20, caps: 20, 'caps-lock': 20,
40154     // Escape key, on Mac: ⎋, on Windows: Esc
40155     '⎋': 27, escape: 27, esc: 27,
40156     // Space key
40157     space: 32,
40158     // Page-Up key, or pgup, on Mac: ↖
40159     '↖': 33, pgup: 33, 'page-up': 33,
40160     // Page-Down key, or pgdown, on Mac: ↘
40161     '↘': 34, pgdown: 34, 'page-down': 34,
40162     // END key, on Mac: ⇟
40163     '⇟': 35, end: 35,
40164     // HOME key, on Mac: ⇞
40165     '⇞': 36, home: 36,
40166     // Insert key, or ins
40167     ins: 45, insert: 45,
40168     // Delete key, on Mac: ⌦ (Delete)
40169     '⌦': 46, del: 46, 'delete': 46,
40170     // Left Arrow Key, or ←
40171     '←': 37, left: 37, 'arrow-left': 37,
40172     // Up Arrow Key, or ↑
40173     '↑': 38, up: 38, 'arrow-up': 38,
40174     // Right Arrow Key, or →
40175     '→': 39, right: 39, 'arrow-right': 39,
40176     // Up Arrow Key, or ↓
40177     '↓': 40, down: 40, 'arrow-down': 40,
40178     // odities, printing characters that come out wrong:
40179     // Firefox Equals
40180     'ffequals': 61,
40181     // Num-Multiply, or *
40182     '*': 106, star: 106, asterisk: 106, multiply: 106,
40183     // Num-Plus or +
40184     '+': 107, 'plus': 107,
40185     // Num-Subtract, or -
40186     '-': 109, subtract: 109,
40187     // Firefox Plus
40188     'ffplus': 171,
40189     // Firefox Minus
40190     'ffminus': 173,
40191     // Semicolon
40192     ';': 186, semicolon: 186,
40193     // = or equals
40194     '=': 187, 'equals': 187,
40195     // Comma, or ,
40196     ',': 188, comma: 188,
40197     // Dash / Underscore key
40198     'dash': 189,
40199     // Period, or ., or full-stop
40200     '.': 190, period: 190, 'full-stop': 190,
40201     // Slash, or /, or forward-slash
40202     '/': 191, slash: 191, 'forward-slash': 191,
40203     // Tick, or `, or back-quote
40204     '`': 192, tick: 192, 'back-quote': 192,
40205     // Open bracket, or [
40206     '[': 219, 'open-bracket': 219,
40207     // Back slash, or \
40208     '\\': 220, 'back-slash': 220,
40209     // Close backet, or ]
40210     ']': 221, 'close-bracket': 221,
40211     // Apostrophe, or Quote, or '
40212     '\'': 222, quote: 222, apostrophe: 222
40213 };
40214
40215 // NUMPAD 0-9
40216 var i$1 = 95;
40217 var n = 0;
40218 while (++i$1 < 106) {
40219     d3keybinding.keyCodes['num-' + n] = i$1;
40220     ++n;
40221 }
40222
40223 // 0-9
40224 i$1 = 47; n = 0;
40225 while (++i$1 < 58) {
40226     d3keybinding.keyCodes[n] = i$1;
40227     ++n;
40228 }
40229
40230 // F1-F25
40231 i$1 = 111; n = 1;
40232 while (++i$1 < 136) {
40233     d3keybinding.keyCodes['f' + n] = i$1;
40234     ++n;
40235 }
40236
40237 // a-z
40238 i$1 = 64;
40239 while (++i$1 < 91) {
40240     d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
40241 }
40242
40243 function tooltip() {
40244   var tooltip = function(selection$$1) {
40245       selection$$1.each(setup);
40246     },
40247     animation = utilFunctor(false),
40248     html$$1 = utilFunctor(false),
40249     title = function() {
40250       var title = this.getAttribute('data-original-title');
40251       if (title) {
40252         return title;
40253       } else {
40254         title = this.getAttribute('title');
40255         this.removeAttribute('title');
40256         this.setAttribute('data-original-title', title);
40257       }
40258       return title;
40259     },
40260     over = 'mouseenter.tooltip',
40261     out = 'mouseleave.tooltip',
40262     placement = utilFunctor('top');
40263
40264
40265   tooltip.title = function(_) {
40266     if (arguments.length) {
40267       title = utilFunctor(_);
40268       return tooltip;
40269     } else {
40270       return title;
40271     }
40272   };
40273
40274
40275   tooltip.html = function(_) {
40276     if (arguments.length) {
40277       html$$1 = utilFunctor(_);
40278       return tooltip;
40279     } else {
40280       return html$$1;
40281     }
40282   };
40283
40284
40285   tooltip.placement = function(_) {
40286     if (arguments.length) {
40287       placement = utilFunctor(_);
40288       return tooltip;
40289     } else {
40290       return placement;
40291     }
40292   };
40293
40294
40295   tooltip.show = function(selection$$1) {
40296     selection$$1.each(show);
40297   };
40298
40299
40300   tooltip.hide = function(selection$$1) {
40301     selection$$1.each(hide);
40302   };
40303
40304
40305   tooltip.toggle = function(selection$$1) {
40306     selection$$1.each(toggle);
40307   };
40308
40309
40310   tooltip.destroy = function(selection$$1) {
40311     selection$$1
40312       .on(over, null)
40313       .on(out, null)
40314       .attr('title', function() {
40315         return this.getAttribute('data-original-title') || this.getAttribute('title');
40316       })
40317       .attr('data-original-title', null)
40318       .selectAll('.tooltip')
40319       .remove();
40320   };
40321
40322
40323   function setup() {
40324     var root = select(this),
40325         animate = animation.apply(this, arguments),
40326         tip = root.selectAll('.tooltip').data([0]);
40327
40328     var enter = tip.enter()
40329       .append('div')
40330       .attr('class', 'tooltip');
40331
40332     enter
40333       .append('div')
40334       .attr('class', 'tooltip-arrow');
40335
40336     enter
40337       .append('div')
40338       .attr('class', 'tooltip-inner');
40339
40340     tip = enter
40341       .merge(tip);
40342
40343     if (animate) {
40344       tip.classed('fade', true);
40345     }
40346
40347     var place = placement.apply(this, arguments);
40348     tip.classed(place, true);
40349
40350     root.on(over, show);
40351     root.on(out, hide);
40352   }
40353
40354
40355   function show() {
40356     var root = select(this),
40357       content = title.apply(this, arguments),
40358       tip = root.selectAll('.tooltip')
40359         .classed('in', true),
40360       markup = html$$1.apply(this, arguments);
40361
40362     tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
40363     var place = placement.apply(this, arguments),
40364       outer = getPosition(root.node()),
40365       inner = getPosition(tip.node()),
40366       pos;
40367
40368     switch (place) {
40369       case 'top':
40370         pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
40371         break;
40372       case 'right':
40373         pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
40374         break;
40375       case 'left':
40376         pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
40377         break;
40378       case 'bottom':
40379         pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
40380         break;
40381     }
40382
40383     if (pos) {
40384       tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
40385     } else {
40386       tip.style('left', null).style('top', null);
40387     }
40388
40389     this.tooltipVisible = true;
40390   }
40391
40392
40393   function hide() {
40394     select(this).selectAll('.tooltip')
40395       .classed('in', false);
40396
40397     this.tooltipVisible = false;
40398   }
40399
40400
40401   function toggle() {
40402     if (this.tooltipVisible) {
40403       hide.apply(this, arguments);
40404     } else {
40405       show.apply(this, arguments);
40406     }
40407   }
40408
40409   return tooltip;
40410 }
40411
40412
40413 function getPosition(node) {
40414   var mode = select(node).style('position');
40415   if (mode === 'absolute' || mode === 'static') {
40416     return {
40417       x: node.offsetLeft,
40418       y: node.offsetTop,
40419       w: node.offsetWidth,
40420       h: node.offsetHeight
40421     };
40422   } else {
40423     return {
40424       x: 0,
40425       y: 0,
40426       w: node.offsetWidth,
40427       h: node.offsetHeight
40428     };
40429   }
40430 }
40431
40432 function svgAreas$$1(projection$$1, context) {
40433     // Patterns only work in Firefox when set directly on element.
40434     // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
40435     var patterns = {
40436         beach: 'beach',
40437         cemetery: 'cemetery',
40438         construction: 'construction',
40439         farm: 'farmland',
40440         farmland: 'farmland',
40441         grave_yard: 'cemetery',
40442         meadow: 'meadow',
40443         military: 'construction',
40444         orchard: 'orchard',
40445         sand: 'beach',
40446         scrub: 'scrub',
40447         wetland: 'wetland',
40448     };
40449
40450     var patternKeys = ['landuse', 'natural', 'amenity'];
40451
40452
40453     function setPattern(d) {
40454         for (var i = 0; i < patternKeys.length; i++) {
40455             if (d.tags.building && d.tags.building !== 'no') continue;
40456
40457             if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
40458                 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
40459                 return;
40460             }
40461         }
40462         this.style.fill = this.style.stroke = '';
40463     }
40464
40465
40466     return function drawAreas(selection$$1, graph, entities, filter) {
40467         var path$$1 = svgPath(projection$$1, graph, true),
40468             areas = {},
40469             multipolygon;
40470
40471         for (var i = 0; i < entities.length; i++) {
40472             var entity = entities[i];
40473             if (entity.geometry(graph) !== 'area') continue;
40474
40475             multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
40476             if (multipolygon) {
40477                 areas[multipolygon.id] = {
40478                     entity: multipolygon.mergeTags(entity.tags),
40479                     area: Math.abs(entity.area(graph))
40480                 };
40481             } else if (!areas[entity.id]) {
40482                 areas[entity.id] = {
40483                     entity: entity,
40484                     area: Math.abs(entity.area(graph))
40485                 };
40486             }
40487         }
40488
40489         areas = values(areas).filter(function hasPath(a) { return path$$1(a.entity); });
40490         areas.sort(function areaSort(a, b) { return b.area - a.area; });
40491         areas = lodash.map(areas, 'entity');
40492
40493         var strokes = areas.filter(function(area$$1) {
40494             return area$$1.type === 'way';
40495         });
40496
40497         var data = {
40498             clip: areas,
40499             shadow: strokes,
40500             stroke: strokes,
40501             fill: areas
40502         };
40503
40504         var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
40505            .filter(filter)
40506            .data(data.clip, osmEntity$$1.key);
40507
40508         clipPaths.exit()
40509            .remove();
40510
40511         var clipPathsEnter = clipPaths.enter()
40512            .append('clipPath')
40513            .attr('class', 'clipPath')
40514            .attr('id', function(entity) { return entity.id + '-clippath'; });
40515
40516         clipPathsEnter
40517            .append('path');
40518
40519         clipPaths.merge(clipPathsEnter)
40520            .selectAll('path')
40521            .attr('d', path$$1);
40522
40523
40524         var layer = selection$$1.selectAll('.layer-areas');
40525
40526         var areagroup = layer
40527             .selectAll('g.areagroup')
40528             .data(['fill', 'shadow', 'stroke']);
40529
40530         areagroup = areagroup.enter()
40531             .append('g')
40532             .attr('class', function(d) { return 'areagroup area-' + d; })
40533             .merge(areagroup);
40534
40535         var paths = areagroup
40536             .selectAll('path')
40537             .filter(filter)
40538             .data(function(layer) { return data[layer]; }, osmEntity$$1.key);
40539
40540         paths.exit()
40541             .remove();
40542
40543         var fills = selection$$1.selectAll('.area-fill path.area').nodes();
40544
40545         var bisect = bisector(function(node) {
40546             return -node.__data__.area(graph);
40547         }).left;
40548
40549         function sortedByArea(entity) {
40550             if (this._parent.__data__ === 'fill') {
40551                 return fills[bisect(fills, -entity.area(graph))];
40552             }
40553         }
40554
40555         paths = paths.enter()
40556             .insert('path', sortedByArea)
40557             .merge(paths)
40558             .each(function(entity) {
40559                 var layer = this.parentNode.__data__;
40560
40561                 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
40562
40563                 if (layer === 'fill') {
40564                     this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
40565                     setPattern.apply(this, arguments);
40566                 }
40567             })
40568             .call(svgTagClasses())
40569             .attr('d', path$$1);
40570     };
40571 }
40572
40573 function svgDebug(projection$$1, context) {
40574
40575     function multipolygons(imagery) {
40576         return imagery.map(function(data$$1) {
40577             return {
40578                 type: 'MultiPolygon',
40579                 coordinates: [ data$$1.polygon ]
40580             };
40581         });
40582     }
40583
40584     function drawDebug(selection$$1) {
40585         var showsTile = context.getDebug('tile'),
40586             showsCollision = context.getDebug('collision'),
40587             showsImagery = context.getDebug('imagery'),
40588             showsImperial = context.getDebug('imperial'),
40589             showsDriveLeft = context.getDebug('driveLeft'),
40590             path$$1 = index$4(projection$$1);
40591
40592
40593         var debugData = [];
40594         if (showsTile) {
40595             debugData.push({ class: 'red', label: 'tile' });
40596         }
40597         if (showsCollision) {
40598             debugData.push({ class: 'yellow', label: 'collision' });
40599         }
40600         if (showsImagery) {
40601             debugData.push({ class: 'orange', label: 'imagery' });
40602         }
40603         if (showsImperial) {
40604             debugData.push({ class: 'cyan', label: 'imperial' });
40605         }
40606         if (showsDriveLeft) {
40607             debugData.push({ class: 'green', label: 'driveLeft' });
40608         }
40609
40610
40611         var legend = select('#content')
40612             .selectAll('.debug-legend')
40613             .data(debugData.length ? [0] : []);
40614
40615         legend.exit()
40616             .remove();
40617
40618         legend = legend.enter()
40619             .append('div')
40620             .attr('class', 'fillD debug-legend')
40621             .merge(legend);
40622
40623
40624         var legendItems = legend.selectAll('.debug-legend-item')
40625             .data(debugData, function(d) { return d.label; });
40626
40627         legendItems.exit()
40628             .remove();
40629
40630         legendItems.enter()
40631             .append('span')
40632             .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
40633             .text(function(d) { return d.label; });
40634
40635
40636         var layer = selection$$1.selectAll('.layer-debug')
40637             .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
40638
40639         layer.exit()
40640             .remove();
40641
40642         layer = layer.enter()
40643             .append('g')
40644             .attr('class', 'layer-debug')
40645             .merge(layer);
40646
40647
40648         var extent$$1 = context.map().extent(),
40649             dataImagery = data.imagery || [],
40650             availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
40651                 if (!source.polygon) return false;
40652                 return source.polygon.some(function(polygon) {
40653                     return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
40654                 });
40655             }));
40656
40657         var imagery = layer.selectAll('path.debug-imagery')
40658             .data(showsImagery ? availableImagery : []);
40659
40660         imagery.exit()
40661             .remove();
40662
40663         imagery.enter()
40664             .append('path')
40665             .attr('class', 'debug-imagery debug orange');
40666
40667
40668         var imperial = layer
40669             .selectAll('path.debug-imperial')
40670             .data(showsImperial ? [dataImperial] : []);
40671
40672         imperial.exit()
40673             .remove();
40674
40675         imperial.enter()
40676             .append('path')
40677             .attr('class', 'debug-imperial debug cyan');
40678
40679
40680         var driveLeft = layer
40681             .selectAll('path.debug-drive-left')
40682             .data(showsDriveLeft ? [dataDriveLeft] : []);
40683
40684         driveLeft.exit()
40685             .remove();
40686
40687         driveLeft.enter()
40688             .append('path')
40689             .attr('class', 'debug-drive-left debug green');
40690
40691
40692         // update
40693         layer.selectAll('path')
40694             .attr('d', path$$1);
40695     }
40696
40697
40698     // This looks strange because `enabled` methods on other layers are
40699     // chainable getter/setters, and this one is just a getter.
40700     drawDebug.enabled = function() {
40701         if (!arguments.length) {
40702             return context.getDebug('tile') ||
40703                 context.getDebug('collision') ||
40704                 context.getDebug('imagery') ||
40705                 context.getDebug('imperial') ||
40706                 context.getDebug('driveLeft');
40707         } else {
40708             return this;
40709         }
40710     };
40711
40712
40713     return drawDebug;
40714 }
40715
40716 /*
40717     A standalone SVG element that contains only a `defs` sub-element. To be
40718     used once globally, since defs IDs must be unique within a document.
40719 */
40720 function svgDefs(context) {
40721
40722     function SVGSpriteDefinition(id, href) {
40723         return function(defs) {
40724             request(href)
40725                 .mimeType('image/svg+xml')
40726                 .response(function(xhr) { return xhr.responseXML; })
40727                 .get(function(err, svg) {
40728                     if (err) return;
40729                     defs.node().appendChild(
40730                         select(svg.documentElement).attr('id', id).node()
40731                     );
40732                 });
40733         };
40734     }
40735
40736
40737     return function drawDefs(selection$$1) {
40738         var defs = selection$$1.append('defs');
40739
40740         // marker
40741         defs.append('marker')
40742             .attr('id', 'oneway-marker')
40743             .attr('viewBox', '0 0 10 10')
40744             .attr('refY', 2.5)
40745             .attr('refX', 5)
40746             .attr('markerWidth', 2)
40747             .attr('markerHeight', 2)
40748             .attr('markerUnits', 'strokeWidth')
40749             .attr('orient', 'auto')
40750
40751             .append('path')
40752             .attr('class', 'oneway')
40753             .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')
40754             .attr('stroke', 'none')
40755             .attr('fill', '#000')
40756             .attr('opacity', '0.75');
40757
40758         // patterns
40759         var patterns = defs.selectAll('pattern')
40760             .data([
40761                 // pattern name, pattern image name
40762                 ['wetland', 'wetland'],
40763                 ['construction', 'construction'],
40764                 ['cemetery', 'cemetery'],
40765                 ['orchard', 'orchard'],
40766                 ['farmland', 'farmland'],
40767                 ['beach', 'dots'],
40768                 ['scrub', 'dots'],
40769                 ['meadow', 'dots']
40770             ])
40771             .enter()
40772             .append('pattern')
40773             .attr('id', function (d) {
40774                 return 'pattern-' + d[0];
40775             })
40776             .attr('width', 32)
40777             .attr('height', 32)
40778             .attr('patternUnits', 'userSpaceOnUse');
40779
40780         patterns.append('rect')
40781             .attr('x', 0)
40782             .attr('y', 0)
40783             .attr('width', 32)
40784             .attr('height', 32)
40785             .attr('class', function (d) {
40786                     return 'pattern-color-' + d[0];
40787             });
40788
40789         patterns.append('image')
40790             .attr('x', 0)
40791             .attr('y', 0)
40792             .attr('width', 32)
40793             .attr('height', 32)
40794             .attr('xlink:href', function (d) {
40795                 return context.imagePath('pattern/' + d[1] + '.png');
40796             });
40797
40798         // clip paths
40799         defs.selectAll()
40800             .data([12, 18, 20, 32, 45])
40801             .enter()
40802             .append('clipPath')
40803             .attr('id', function (d) {
40804                 return 'clip-square-' + d;
40805             })
40806             .append('rect')
40807             .attr('x', 0)
40808             .attr('y', 0)
40809             .attr('width', function (d) {
40810                 return d;
40811             })
40812             .attr('height', function (d) {
40813                 return d;
40814             });
40815
40816         defs.call(SVGSpriteDefinition(
40817             'iD-sprite',
40818             context.imagePath('iD-sprite.svg')));
40819
40820         defs.call(SVGSpriteDefinition(
40821             'maki-sprite',
40822             context.imagePath('maki-sprite.svg')));
40823     };
40824 }
40825
40826 //[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]
40827 //[4a]          NameChar           ::=          NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
40828 //[5]           Name       ::=          NameStartChar (NameChar)*
40829 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
40830 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
40831 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
40832 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
40833 //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(',')
40834
40835 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
40836 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
40837 var S_TAG = 0;//tag name offerring
40838 var S_ATTR = 1;//attr name offerring 
40839 var S_ATTR_SPACE=2;//attr name end and space offer
40840 var S_EQ = 3;//=space?
40841 var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
40842 var S_ATTR_END = 5;//attr value end and no space(quot end)
40843 var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
40844 var S_TAG_CLOSE = 7;//closed el<el />
40845
40846 function XMLReader(){
40847         
40848 }
40849
40850 XMLReader.prototype = {
40851         parse:function(source,defaultNSMap,entityMap){
40852                 var domBuilder = this.domBuilder;
40853                 domBuilder.startDocument();
40854                 _copy(defaultNSMap ,defaultNSMap = {});
40855                 parse(source,defaultNSMap,entityMap,
40856                                 domBuilder,this.errorHandler);
40857                 domBuilder.endDocument();
40858         }
40859 };
40860 function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
40861         function fixedFromCharCode(code) {
40862                 // String.prototype.fromCharCode does not supports
40863                 // > 2 bytes unicode chars directly
40864                 if (code > 0xffff) {
40865                         code -= 0x10000;
40866                         var surrogate1 = 0xd800 + (code >> 10)
40867                                 , surrogate2 = 0xdc00 + (code & 0x3ff);
40868
40869                         return String.fromCharCode(surrogate1, surrogate2);
40870                 } else {
40871                         return String.fromCharCode(code);
40872                 }
40873         }
40874         function entityReplacer(a){
40875                 var k = a.slice(1,-1);
40876                 if(k in entityMap){
40877                         return entityMap[k]; 
40878                 }else if(k.charAt(0) === '#'){
40879                         return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
40880                 }else{
40881                         errorHandler.error('entity not found:'+a);
40882                         return a;
40883                 }
40884         }
40885         function appendText(end){//has some bugs
40886                 if(end>start){
40887                         var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
40888                         locator&&position(start);
40889                         domBuilder.characters(xt,0,end-start);
40890                         start = end;
40891                 }
40892         }
40893         function position(p,m){
40894                 while(p>=lineEnd && (m = linePattern.exec(source))){
40895                         lineStart = m.index;
40896                         lineEnd = lineStart + m[0].length;
40897                         locator.lineNumber++;
40898                         //console.log('line++:',locator,startPos,endPos)
40899                 }
40900                 locator.columnNumber = p-lineStart+1;
40901         }
40902         var lineStart = 0;
40903         var lineEnd = 0;
40904         var linePattern = /.*(?:\r\n?|\n)|.*$/g;
40905         var locator = domBuilder.locator;
40906         
40907         var parseStack = [{currentNSMap:defaultNSMapCopy}];
40908         var closeMap = {};
40909         var start = 0;
40910         while(true){
40911                 try{
40912                         var tagStart = source.indexOf('<',start);
40913                         if(tagStart<0){
40914                                 if(!source.substr(start).match(/^\s*$/)){
40915                                         var doc = domBuilder.doc;
40916                                 var text = doc.createTextNode(source.substr(start));
40917                                 doc.appendChild(text);
40918                                 domBuilder.currentElement = text;
40919                                 }
40920                                 return;
40921                         }
40922                         if(tagStart>start){
40923                                 appendText(tagStart);
40924                         }
40925                         switch(source.charAt(tagStart+1)){
40926                         case '/':
40927                                 var end = source.indexOf('>',tagStart+3);
40928                                 var tagName = source.substring(tagStart+2,end);
40929                                 var config = parseStack.pop();
40930                                 if(end<0){
40931                                         
40932                                 tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
40933                                 //console.error('#@@@@@@'+tagName)
40934                                 errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
40935                                 end = tagStart+1+tagName.length;
40936                         }else if(tagName.match(/\s</)){
40937                                 tagName = tagName.replace(/[\s<].*/,'');
40938                                 errorHandler.error("end tag name: "+tagName+' maybe not complete');
40939                                 end = tagStart+1+tagName.length;
40940                                 }
40941                                 //console.error(parseStack.length,parseStack)
40942                                 //console.error(config);
40943                                 var localNSMap = config.localNSMap;
40944                                 var endMatch = config.tagName == tagName;
40945                                 var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase();
40946                         if(endIgnoreCaseMach){
40947                                 domBuilder.endElement(config.uri,config.localName,tagName);
40948                                         if(localNSMap){
40949                                                 for(var prefix in localNSMap){
40950                                                         domBuilder.endPrefixMapping(prefix) ;
40951                                                 }
40952                                         }
40953                                         if(!endMatch){
40954                                 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
40955                                         }
40956                         }else{
40957                                 parseStack.push(config);
40958                         }
40959                                 
40960                                 end++;
40961                                 break;
40962                                 // end elment
40963                         case '?':// <?...?>
40964                                 locator&&position(tagStart);
40965                                 end = parseInstruction(source,tagStart,domBuilder);
40966                                 break;
40967                         case '!':// <!doctype,<![CDATA,<!--
40968                                 locator&&position(tagStart);
40969                                 end = parseDCC(source,tagStart,domBuilder,errorHandler);
40970                                 break;
40971                         default:
40972                                 locator&&position(tagStart);
40973                                 var el = new ElementAttributes();
40974                                 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
40975                                 //elStartEnd
40976                                 var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
40977                                 var len = el.length;
40978                                 
40979                                 
40980                                 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
40981                                         el.closed = true;
40982                                         if(!entityMap.nbsp){
40983                                                 errorHandler.warning('unclosed xml attribute');
40984                                         }
40985                                 }
40986                                 if(locator && len){
40987                                         var locator2 = copyLocator(locator,{});
40988                                         //try{//attribute position fixed
40989                                         for(var i = 0;i<len;i++){
40990                                                 var a = el[i];
40991                                                 position(a.offset);
40992                                                 a.locator = copyLocator(locator,{});
40993                                         }
40994                                         //}catch(e){console.error('@@@@@'+e)}
40995                                         domBuilder.locator = locator2;
40996                                         if(appendElement(el,domBuilder,currentNSMap)){
40997                                                 parseStack.push(el);
40998                                         }
40999                                         domBuilder.locator = locator;
41000                                 }else{
41001                                         if(appendElement(el,domBuilder,currentNSMap)){
41002                                                 parseStack.push(el);
41003                                         }
41004                                 }
41005                                 
41006                                 
41007                                 
41008                                 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
41009                                         end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
41010                                 }else{
41011                                         end++;
41012                                 }
41013                         }
41014                 }catch(e){
41015                         errorHandler.error('element parse error: '+e);
41016                         //errorHandler.error('element parse error: '+e);
41017                         end = -1;
41018                         //throw e;
41019                 }
41020                 if(end>start){
41021                         start = end;
41022                 }else{
41023                         //TODO: 这里有可能sax回退,有位置错误风险
41024                         appendText(Math.max(tagStart,start)+1);
41025                 }
41026         }
41027 }
41028 function copyLocator(f,t){
41029         t.lineNumber = f.lineNumber;
41030         t.columnNumber = f.columnNumber;
41031         return t;
41032 }
41033
41034 /**
41035  * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
41036  * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
41037  */
41038 function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
41039         var attrName;
41040         var value;
41041         var p = ++start;
41042         var s = S_TAG;//status
41043         while(true){
41044                 var c = source.charAt(p);
41045                 switch(c){
41046                 case '=':
41047                         if(s === S_ATTR){//attrName
41048                                 attrName = source.slice(start,p);
41049                                 s = S_EQ;
41050                         }else if(s === S_ATTR_SPACE){
41051                                 s = S_EQ;
41052                         }else{
41053                                 //fatalError: equal must after attrName or space after attrName
41054                                 throw new Error('attribute equal must after attrName');
41055                         }
41056                         break;
41057                 case '\'':
41058                 case '"':
41059                         if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
41060                                 ){//equal
41061                                 if(s === S_ATTR){
41062                                         errorHandler.warning('attribute value must after "="');
41063                                         attrName = source.slice(start,p);
41064                                 }
41065                                 start = p+1;
41066                                 p = source.indexOf(c,start);
41067                                 if(p>0){
41068                                         value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41069                                         el.add(attrName,value,start-1);
41070                                         s = S_ATTR_END;
41071                                 }else{
41072                                         //fatalError: no end quot match
41073                                         throw new Error('attribute value no end \''+c+'\' match');
41074                                 }
41075                         }else if(s == S_ATTR_NOQUOT_VALUE){
41076                                 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41077                                 //console.log(attrName,value,start,p)
41078                                 el.add(attrName,value,start);
41079                                 //console.dir(el)
41080                                 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
41081                                 start = p+1;
41082                                 s = S_ATTR_END;
41083                         }else{
41084                                 //fatalError: no equal before
41085                                 throw new Error('attribute value must after "="');
41086                         }
41087                         break;
41088                 case '/':
41089                         switch(s){
41090                         case S_TAG:
41091                                 el.setTagName(source.slice(start,p));
41092                         case S_ATTR_END:
41093                         case S_TAG_SPACE:
41094                         case S_TAG_CLOSE:
41095                                 s =S_TAG_CLOSE;
41096                                 el.closed = true;
41097                         case S_ATTR_NOQUOT_VALUE:
41098                         case S_ATTR:
41099                         case S_ATTR_SPACE:
41100                                 break;
41101                         //case S_EQ:
41102                         default:
41103                                 throw new Error("attribute invalid close char('/')")
41104                         }
41105                         break;
41106                 case ''://end document
41107                         //throw new Error('unexpected end of input')
41108                         errorHandler.error('unexpected end of input');
41109                         if(s == S_TAG){
41110                                 el.setTagName(source.slice(start,p));
41111                         }
41112                         return p;
41113                 case '>':
41114                         switch(s){
41115                         case S_TAG:
41116                                 el.setTagName(source.slice(start,p));
41117                         case S_ATTR_END:
41118                         case S_TAG_SPACE:
41119                         case S_TAG_CLOSE:
41120                                 break;//normal
41121                         case S_ATTR_NOQUOT_VALUE://Compatible state
41122                         case S_ATTR:
41123                                 value = source.slice(start,p);
41124                                 if(value.slice(-1) === '/'){
41125                                         el.closed  = true;
41126                                         value = value.slice(0,-1);
41127                                 }
41128                         case S_ATTR_SPACE:
41129                                 if(s === S_ATTR_SPACE){
41130                                         value = attrName;
41131                                 }
41132                                 if(s == S_ATTR_NOQUOT_VALUE){
41133                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41134                                         el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
41135                                 }else{
41136                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){
41137                                                 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
41138                                         }
41139                                         el.add(value,value,start);
41140                                 }
41141                                 break;
41142                         case S_EQ:
41143                                 throw new Error('attribute value missed!!');
41144                         }
41145 //                      console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
41146                         return p;
41147                 /*xml space '\x20' | #x9 | #xD | #xA; */
41148                 case '\u0080':
41149                         c = ' ';
41150                 default:
41151                         if(c<= ' '){//space
41152                                 switch(s){
41153                                 case S_TAG:
41154                                         el.setTagName(source.slice(start,p));//tagName
41155                                         s = S_TAG_SPACE;
41156                                         break;
41157                                 case S_ATTR:
41158                                         attrName = source.slice(start,p);
41159                                         s = S_ATTR_SPACE;
41160                                         break;
41161                                 case S_ATTR_NOQUOT_VALUE:
41162                                         var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41163                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41164                                         el.add(attrName,value,start);
41165                                 case S_ATTR_END:
41166                                         s = S_TAG_SPACE;
41167                                         break;
41168                                 //case S_TAG_SPACE:
41169                                 //case S_EQ:
41170                                 //case S_ATTR_SPACE:
41171                                 //      void();break;
41172                                 //case S_TAG_CLOSE:
41173                                         //ignore warning
41174                                 }
41175                         }else{//not space
41176 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
41177 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
41178                                 switch(s){
41179                                 //case S_TAG:void();break;
41180                                 //case S_ATTR:void();break;
41181                                 //case S_ATTR_NOQUOT_VALUE:void();break;
41182                                 case S_ATTR_SPACE:
41183                                         var tagName =  el.tagName;
41184                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){
41185                                                 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!');
41186                                         }
41187                                         el.add(attrName,attrName,start);
41188                                         start = p;
41189                                         s = S_ATTR;
41190                                         break;
41191                                 case S_ATTR_END:
41192                                         errorHandler.warning('attribute space is required"'+attrName+'"!!');
41193                                 case S_TAG_SPACE:
41194                                         s = S_ATTR;
41195                                         start = p;
41196                                         break;
41197                                 case S_EQ:
41198                                         s = S_ATTR_NOQUOT_VALUE;
41199                                         start = p;
41200                                         break;
41201                                 case S_TAG_CLOSE:
41202                                         throw new Error("elements closed character '/' and '>' must be connected to");
41203                                 }
41204                         }
41205                 }//end outer switch
41206                 //console.log('p++',p)
41207                 p++;
41208         }
41209 }
41210 /**
41211  * @return true if has new namespace define
41212  */
41213 function appendElement(el,domBuilder,currentNSMap){
41214         var tagName = el.tagName;
41215         var localNSMap = null;
41216         //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
41217         var i = el.length;
41218         while(i--){
41219                 var a = el[i];
41220                 var qName = a.qName;
41221                 var value = a.value;
41222                 var nsp = qName.indexOf(':');
41223                 if(nsp>0){
41224                         var prefix = a.prefix = qName.slice(0,nsp);
41225                         var localName = qName.slice(nsp+1);
41226                         var nsPrefix = prefix === 'xmlns' && localName;
41227                 }else{
41228                         localName = qName;
41229                         prefix = null;
41230                         nsPrefix = qName === 'xmlns' && '';
41231                 }
41232                 //can not set prefix,because prefix !== ''
41233                 a.localName = localName ;
41234                 //prefix == null for no ns prefix attribute 
41235                 if(nsPrefix !== false){//hack!!
41236                         if(localNSMap == null){
41237                                 localNSMap = {};
41238                                 //console.log(currentNSMap,0)
41239                                 _copy(currentNSMap,currentNSMap={});
41240                                 //console.log(currentNSMap,1)
41241                         }
41242                         currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
41243                         a.uri = 'http://www.w3.org/2000/xmlns/';
41244                         domBuilder.startPrefixMapping(nsPrefix, value); 
41245                 }
41246         }
41247         var i = el.length;
41248         while(i--){
41249                 a = el[i];
41250                 var prefix = a.prefix;
41251                 if(prefix){//no prefix attribute has no namespace
41252                         if(prefix === 'xml'){
41253                                 a.uri = 'http://www.w3.org/XML/1998/namespace';
41254                         }if(prefix !== 'xmlns'){
41255                                 a.uri = currentNSMap[prefix || ''];
41256                                 
41257                                 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
41258                         }
41259                 }
41260         }
41261         var nsp = tagName.indexOf(':');
41262         if(nsp>0){
41263                 prefix = el.prefix = tagName.slice(0,nsp);
41264                 localName = el.localName = tagName.slice(nsp+1);
41265         }else{
41266                 prefix = null;//important!!
41267                 localName = el.localName = tagName;
41268         }
41269         //no prefix element has default namespace
41270         var ns = el.uri = currentNSMap[prefix || ''];
41271         domBuilder.startElement(ns,localName,tagName,el);
41272         //endPrefixMapping and startPrefixMapping have not any help for dom builder
41273         //localNSMap = null
41274         if(el.closed){
41275                 domBuilder.endElement(ns,localName,tagName);
41276                 if(localNSMap){
41277                         for(prefix in localNSMap){
41278                                 domBuilder.endPrefixMapping(prefix); 
41279                         }
41280                 }
41281         }else{
41282                 el.currentNSMap = currentNSMap;
41283                 el.localNSMap = localNSMap;
41284                 //parseStack.push(el);
41285                 return true;
41286         }
41287 }
41288 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
41289         if(/^(?:script|textarea)$/i.test(tagName)){
41290                 var elEndStart =  source.indexOf('</'+tagName+'>',elStartEnd);
41291                 var text = source.substring(elStartEnd+1,elEndStart);
41292                 if(/[&<]/.test(text)){
41293                         if(/^script$/i.test(tagName)){
41294                                 //if(!/\]\]>/.test(text)){
41295                                         //lexHandler.startCDATA();
41296                                         domBuilder.characters(text,0,text.length);
41297                                         //lexHandler.endCDATA();
41298                                         return elEndStart;
41299                                 //}
41300                         }//}else{//text area
41301                                 text = text.replace(/&#?\w+;/g,entityReplacer);
41302                                 domBuilder.characters(text,0,text.length);
41303                                 return elEndStart;
41304                         //}
41305                         
41306                 }
41307         }
41308         return elStartEnd+1;
41309 }
41310 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
41311         //if(tagName in closeMap){
41312         var pos = closeMap[tagName];
41313         if(pos == null){
41314                 //console.log(tagName)
41315                 pos =  source.lastIndexOf('</'+tagName+'>');
41316                 if(pos<elStartEnd){//忘记闭合
41317                         pos = source.lastIndexOf('</'+tagName);
41318                 }
41319                 closeMap[tagName] =pos;
41320         }
41321         return pos<elStartEnd;
41322         //} 
41323 }
41324 function _copy(source,target){
41325         for(var n in source){target[n] = source[n];}
41326 }
41327 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
41328         var next= source.charAt(start+2);
41329         switch(next){
41330         case '-':
41331                 if(source.charAt(start + 3) === '-'){
41332                         var end = source.indexOf('-->',start+4);
41333                         //append comment source.substring(4,end)//<!--
41334                         if(end>start){
41335                                 domBuilder.comment(source,start+4,end-start-4);
41336                                 return end+3;
41337                         }else{
41338                                 errorHandler.error("Unclosed comment");
41339                                 return -1;
41340                         }
41341                 }else{
41342                         //error
41343                         return -1;
41344                 }
41345         default:
41346                 if(source.substr(start+3,6) == 'CDATA['){
41347                         var end = source.indexOf(']]>',start+9);
41348                         domBuilder.startCDATA();
41349                         domBuilder.characters(source,start+9,end-start-9);
41350                         domBuilder.endCDATA(); 
41351                         return end+3;
41352                 }
41353                 //<!DOCTYPE
41354                 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId) 
41355                 var matchs = split(source,start);
41356                 var len = matchs.length;
41357                 if(len>1 && /!doctype/i.test(matchs[0][0])){
41358                         var name = matchs[1][0];
41359                         var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
41360                         var sysid = len>4 && matchs[4][0];
41361                         var lastMatch = matchs[len-1];
41362                         domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
41363                                         sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
41364                         domBuilder.endDTD();
41365                         
41366                         return lastMatch.index+lastMatch[0].length
41367                 }
41368         }
41369         return -1;
41370 }
41371
41372
41373
41374 function parseInstruction(source,start,domBuilder){
41375         var end = source.indexOf('?>',start);
41376         if(end){
41377                 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
41378                 if(match){
41379                         var len = match[0].length;
41380                         domBuilder.processingInstruction(match[1], match[2]) ;
41381                         return end+2;
41382                 }else{//error
41383                         return -1;
41384                 }
41385         }
41386         return -1;
41387 }
41388
41389 /**
41390  * @param source
41391  */
41392 function ElementAttributes(source){
41393         
41394 }
41395 ElementAttributes.prototype = {
41396         setTagName:function(tagName){
41397                 if(!tagNamePattern.test(tagName)){
41398                         throw new Error('invalid tagName:'+tagName)
41399                 }
41400                 this.tagName = tagName;
41401         },
41402         add:function(qName,value,offset){
41403                 if(!tagNamePattern.test(qName)){
41404                         throw new Error('invalid attribute:'+qName)
41405                 }
41406                 this[this.length++] = {qName:qName,value:value,offset:offset};
41407         },
41408         length:0,
41409         getLocalName:function(i){return this[i].localName},
41410         getLocator:function(i){return this[i].locator},
41411         getQName:function(i){return this[i].qName},
41412         getURI:function(i){return this[i].uri},
41413         getValue:function(i){return this[i].value}
41414 //      ,getIndex:function(uri, localName)){
41415 //              if(localName){
41416 //                      
41417 //              }else{
41418 //                      var qName = uri
41419 //              }
41420 //      },
41421 //      getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
41422 //      getType:function(uri,localName){}
41423 //      getType:function(i){},
41424 };
41425
41426
41427
41428
41429 function _set_proto_(thiz,parent){
41430         thiz.__proto__ = parent;
41431         return thiz;
41432 }
41433 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
41434         _set_proto_ = function(thiz,parent){
41435                 function p(){}
41436                 p.prototype = parent;
41437                 p = new p();
41438                 for(parent in thiz){
41439                         p[parent] = thiz[parent];
41440                 }
41441                 return p;
41442         };
41443 }
41444
41445 function split(source,start){
41446         var match;
41447         var buf = [];
41448         var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
41449         reg.lastIndex = start;
41450         reg.exec(source);//skip <
41451         while(match = reg.exec(source)){
41452                 buf.push(match);
41453                 if(match[1])return buf;
41454         }
41455 }
41456
41457 var XMLReader_1 = XMLReader;
41458
41459 var sax = {
41460         XMLReader: XMLReader_1
41461 };
41462
41463 /*
41464  * DOM Level 2
41465  * Object DOMException
41466  * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
41467  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
41468  */
41469
41470 function copy$1(src,dest){
41471         for(var p in src){
41472                 dest[p] = src[p];
41473         }
41474 }
41475 /**
41476 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
41477 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
41478  */
41479 function _extends(Class,Super){
41480         var pt = Class.prototype;
41481         if(Object.create){
41482                 var ppt = Object.create(Super.prototype);
41483                 pt.__proto__ = ppt;
41484         }
41485         if(!(pt instanceof Super)){
41486                 function t(){}
41487                 t.prototype = Super.prototype;
41488                 t = new t();
41489                 copy$1(pt,t);
41490                 Class.prototype = pt = t;
41491         }
41492         if(pt.constructor != Class){
41493                 if(typeof Class != 'function'){
41494                         console.error("unknow Class:"+Class);
41495                 }
41496                 pt.constructor = Class;
41497         }
41498 }
41499 var htmlns = 'http://www.w3.org/1999/xhtml';
41500 // Node Types
41501 var NodeType = {};
41502 var ELEMENT_NODE                = NodeType.ELEMENT_NODE                = 1;
41503 var ATTRIBUTE_NODE              = NodeType.ATTRIBUTE_NODE              = 2;
41504 var TEXT_NODE                   = NodeType.TEXT_NODE                   = 3;
41505 var CDATA_SECTION_NODE          = NodeType.CDATA_SECTION_NODE          = 4;
41506 var ENTITY_REFERENCE_NODE       = NodeType.ENTITY_REFERENCE_NODE       = 5;
41507 var ENTITY_NODE                 = NodeType.ENTITY_NODE                 = 6;
41508 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
41509 var COMMENT_NODE                = NodeType.COMMENT_NODE                = 8;
41510 var DOCUMENT_NODE               = NodeType.DOCUMENT_NODE               = 9;
41511 var DOCUMENT_TYPE_NODE          = NodeType.DOCUMENT_TYPE_NODE          = 10;
41512 var DOCUMENT_FRAGMENT_NODE      = NodeType.DOCUMENT_FRAGMENT_NODE      = 11;
41513 var NOTATION_NODE               = NodeType.NOTATION_NODE               = 12;
41514
41515 // ExceptionCode
41516 var ExceptionCode = {};
41517 var ExceptionMessage = {};
41518 var INDEX_SIZE_ERR              = ExceptionCode.INDEX_SIZE_ERR              = ((ExceptionMessage[1]="Index size error"),1);
41519 var DOMSTRING_SIZE_ERR          = ExceptionCode.DOMSTRING_SIZE_ERR          = ((ExceptionMessage[2]="DOMString size error"),2);
41520 var HIERARCHY_REQUEST_ERR       = ExceptionCode.HIERARCHY_REQUEST_ERR       = ((ExceptionMessage[3]="Hierarchy request error"),3);
41521 var WRONG_DOCUMENT_ERR          = ExceptionCode.WRONG_DOCUMENT_ERR          = ((ExceptionMessage[4]="Wrong document"),4);
41522 var INVALID_CHARACTER_ERR       = ExceptionCode.INVALID_CHARACTER_ERR       = ((ExceptionMessage[5]="Invalid character"),5);
41523 var NO_DATA_ALLOWED_ERR         = ExceptionCode.NO_DATA_ALLOWED_ERR         = ((ExceptionMessage[6]="No data allowed"),6);
41524 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
41525 var NOT_FOUND_ERR               = ExceptionCode.NOT_FOUND_ERR               = ((ExceptionMessage[8]="Not found"),8);
41526 var NOT_SUPPORTED_ERR           = ExceptionCode.NOT_SUPPORTED_ERR           = ((ExceptionMessage[9]="Not supported"),9);
41527 var INUSE_ATTRIBUTE_ERR         = ExceptionCode.INUSE_ATTRIBUTE_ERR         = ((ExceptionMessage[10]="Attribute in use"),10);
41528 //level2
41529 var INVALID_STATE_ERR           = ExceptionCode.INVALID_STATE_ERR               = ((ExceptionMessage[11]="Invalid state"),11);
41530 var SYNTAX_ERR                  = ExceptionCode.SYNTAX_ERR                      = ((ExceptionMessage[12]="Syntax error"),12);
41531 var INVALID_MODIFICATION_ERR    = ExceptionCode.INVALID_MODIFICATION_ERR        = ((ExceptionMessage[13]="Invalid modification"),13);
41532 var NAMESPACE_ERR               = ExceptionCode.NAMESPACE_ERR                   = ((ExceptionMessage[14]="Invalid namespace"),14);
41533 var INVALID_ACCESS_ERR          = ExceptionCode.INVALID_ACCESS_ERR              = ((ExceptionMessage[15]="Invalid access"),15);
41534
41535
41536 function DOMException(code, message) {
41537         if(message instanceof Error){
41538                 var error = message;
41539         }else{
41540                 error = this;
41541                 Error.call(this, ExceptionMessage[code]);
41542                 this.message = ExceptionMessage[code];
41543                 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
41544         }
41545         error.code = code;
41546         if(message) this.message = this.message + ": " + message;
41547         return error;
41548 }
41549 DOMException.prototype = Error.prototype;
41550 copy$1(ExceptionCode,DOMException);
41551 /**
41552  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
41553  * 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.
41554  * The items in the NodeList are accessible via an integral index, starting from 0.
41555  */
41556 function NodeList() {
41557 }
41558 NodeList.prototype = {
41559         /**
41560          * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
41561          * @standard level1
41562          */
41563         length:0, 
41564         /**
41565          * 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.
41566          * @standard level1
41567          * @param index  unsigned long 
41568          *   Index into the collection.
41569          * @return Node
41570          *      The node at the indexth position in the NodeList, or null if that is not a valid index. 
41571          */
41572         item: function(index) {
41573                 return this[index] || null;
41574         },
41575         toString:function(isHTML,nodeFilter){
41576                 for(var buf = [], i = 0;i<this.length;i++){
41577                         serializeToString(this[i],buf,isHTML,nodeFilter);
41578                 }
41579                 return buf.join('');
41580         }
41581 };
41582 function LiveNodeList(node,refresh){
41583         this._node = node;
41584         this._refresh = refresh;
41585         _updateLiveList(this);
41586 }
41587 function _updateLiveList(list){
41588         var inc = list._node._inc || list._node.ownerDocument._inc;
41589         if(list._inc != inc){
41590                 var ls = list._refresh(list._node);
41591                 //console.log(ls.length)
41592                 __set__(list,'length',ls.length);
41593                 copy$1(ls,list);
41594                 list._inc = inc;
41595         }
41596 }
41597 LiveNodeList.prototype.item = function(i){
41598         _updateLiveList(this);
41599         return this[i];
41600 };
41601
41602 _extends(LiveNodeList,NodeList);
41603 /**
41604  * 
41605  * 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.
41606  * NamedNodeMap objects in the DOM are live.
41607  * used for attributes or DocumentType entities 
41608  */
41609 function NamedNodeMap() {
41610 }
41611
41612 function _findNodeIndex(list,node){
41613         var i = list.length;
41614         while(i--){
41615                 if(list[i] === node){return i}
41616         }
41617 }
41618
41619 function _addNamedNode(el,list,newAttr,oldAttr){
41620         if(oldAttr){
41621                 list[_findNodeIndex(list,oldAttr)] = newAttr;
41622         }else{
41623                 list[list.length++] = newAttr;
41624         }
41625         if(el){
41626                 newAttr.ownerElement = el;
41627                 var doc = el.ownerDocument;
41628                 if(doc){
41629                         oldAttr && _onRemoveAttribute(doc,el,oldAttr);
41630                         _onAddAttribute(doc,el,newAttr);
41631                 }
41632         }
41633 }
41634 function _removeNamedNode(el,list,attr){
41635         //console.log('remove attr:'+attr)
41636         var i = _findNodeIndex(list,attr);
41637         if(i>=0){
41638                 var lastIndex = list.length-1;
41639                 while(i<lastIndex){
41640                         list[i] = list[++i];
41641                 }
41642                 list.length = lastIndex;
41643                 if(el){
41644                         var doc = el.ownerDocument;
41645                         if(doc){
41646                                 _onRemoveAttribute(doc,el,attr);
41647                                 attr.ownerElement = null;
41648                         }
41649                 }
41650         }else{
41651                 throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
41652         }
41653 }
41654 NamedNodeMap.prototype = {
41655         length:0,
41656         item:NodeList.prototype.item,
41657         getNamedItem: function(key) {
41658 //              if(key.indexOf(':')>0 || key == 'xmlns'){
41659 //                      return null;
41660 //              }
41661                 //console.log()
41662                 var i = this.length;
41663                 while(i--){
41664                         var attr = this[i];
41665                         //console.log(attr.nodeName,key)
41666                         if(attr.nodeName == key){
41667                                 return attr;
41668                         }
41669                 }
41670         },
41671         setNamedItem: function(attr) {
41672                 var el = attr.ownerElement;
41673                 if(el && el!=this._ownerElement){
41674                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
41675                 }
41676                 var oldAttr = this.getNamedItem(attr.nodeName);
41677                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41678                 return oldAttr;
41679         },
41680         /* returns Node */
41681         setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
41682                 var el = attr.ownerElement, oldAttr;
41683                 if(el && el!=this._ownerElement){
41684                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
41685                 }
41686                 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
41687                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41688                 return oldAttr;
41689         },
41690
41691         /* returns Node */
41692         removeNamedItem: function(key) {
41693                 var attr = this.getNamedItem(key);
41694                 _removeNamedNode(this._ownerElement,this,attr);
41695                 return attr;
41696                 
41697                 
41698         },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
41699         
41700         //for level2
41701         removeNamedItemNS:function(namespaceURI,localName){
41702                 var attr = this.getNamedItemNS(namespaceURI,localName);
41703                 _removeNamedNode(this._ownerElement,this,attr);
41704                 return attr;
41705         },
41706         getNamedItemNS: function(namespaceURI, localName) {
41707                 var i = this.length;
41708                 while(i--){
41709                         var node = this[i];
41710                         if(node.localName == localName && node.namespaceURI == namespaceURI){
41711                                 return node;
41712                         }
41713                 }
41714                 return null;
41715         }
41716 };
41717 /**
41718  * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
41719  */
41720 function DOMImplementation(/* Object */ features) {
41721         this._features = {};
41722         if (features) {
41723                 for (var feature in features) {
41724                          this._features = features[feature];
41725                 }
41726         }
41727 }
41728
41729 DOMImplementation.prototype = {
41730         hasFeature: function(/* string */ feature, /* string */ version) {
41731                 var versions = this._features[feature.toLowerCase()];
41732                 if (versions && (!version || version in versions)) {
41733                         return true;
41734                 } else {
41735                         return false;
41736                 }
41737         },
41738         // Introduced in DOM Level 2:
41739         createDocument:function(namespaceURI,  qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
41740                 var doc = new Document();
41741                 doc.implementation = this;
41742                 doc.childNodes = new NodeList();
41743                 doc.doctype = doctype;
41744                 if(doctype){
41745                         doc.appendChild(doctype);
41746                 }
41747                 if(qualifiedName){
41748                         var root = doc.createElementNS(namespaceURI,qualifiedName);
41749                         doc.appendChild(root);
41750                 }
41751                 return doc;
41752         },
41753         // Introduced in DOM Level 2:
41754         createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
41755                 var node = new DocumentType();
41756                 node.name = qualifiedName;
41757                 node.nodeName = qualifiedName;
41758                 node.publicId = publicId;
41759                 node.systemId = systemId;
41760                 // Introduced in DOM Level 2:
41761                 //readonly attribute DOMString        internalSubset;
41762                 
41763                 //TODO:..
41764                 //  readonly attribute NamedNodeMap     entities;
41765                 //  readonly attribute NamedNodeMap     notations;
41766                 return node;
41767         }
41768 };
41769
41770
41771 /**
41772  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
41773  */
41774
41775 function Node$2() {
41776 }
41777
41778 Node$2.prototype = {
41779         firstChild : null,
41780         lastChild : null,
41781         previousSibling : null,
41782         nextSibling : null,
41783         attributes : null,
41784         parentNode : null,
41785         childNodes : null,
41786         ownerDocument : null,
41787         nodeValue : null,
41788         namespaceURI : null,
41789         prefix : null,
41790         localName : null,
41791         // Modified in DOM Level 2:
41792         insertBefore:function(newChild, refChild){//raises 
41793                 return _insertBefore(this,newChild,refChild);
41794         },
41795         replaceChild:function(newChild, oldChild){//raises 
41796                 this.insertBefore(newChild,oldChild);
41797                 if(oldChild){
41798                         this.removeChild(oldChild);
41799                 }
41800         },
41801         removeChild:function(oldChild){
41802                 return _removeChild(this,oldChild);
41803         },
41804         appendChild:function(newChild){
41805                 return this.insertBefore(newChild,null);
41806         },
41807         hasChildNodes:function(){
41808                 return this.firstChild != null;
41809         },
41810         cloneNode:function(deep){
41811                 return cloneNode(this.ownerDocument||this,this,deep);
41812         },
41813         // Modified in DOM Level 2:
41814         normalize:function(){
41815                 var child = this.firstChild;
41816                 while(child){
41817                         var next = child.nextSibling;
41818                         if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
41819                                 this.removeChild(next);
41820                                 child.appendData(next.data);
41821                         }else{
41822                                 child.normalize();
41823                                 child = next;
41824                         }
41825                 }
41826         },
41827         // Introduced in DOM Level 2:
41828         isSupported:function(feature, version){
41829                 return this.ownerDocument.implementation.hasFeature(feature,version);
41830         },
41831     // Introduced in DOM Level 2:
41832     hasAttributes:function(){
41833         return this.attributes.length>0;
41834     },
41835     lookupPrefix:function(namespaceURI){
41836         var el = this;
41837         while(el){
41838                 var map = el._nsMap;
41839                 //console.dir(map)
41840                 if(map){
41841                         for(var n in map){
41842                                 if(map[n] == namespaceURI){
41843                                         return n;
41844                                 }
41845                         }
41846                 }
41847                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
41848         }
41849         return null;
41850     },
41851     // Introduced in DOM Level 3:
41852     lookupNamespaceURI:function(prefix){
41853         var el = this;
41854         while(el){
41855                 var map = el._nsMap;
41856                 //console.dir(map)
41857                 if(map){
41858                         if(prefix in map){
41859                                 return map[prefix] ;
41860                         }
41861                 }
41862                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
41863         }
41864         return null;
41865     },
41866     // Introduced in DOM Level 3:
41867     isDefaultNamespace:function(namespaceURI){
41868         var prefix = this.lookupPrefix(namespaceURI);
41869         return prefix == null;
41870     }
41871 };
41872
41873
41874 function _xmlEncoder(c){
41875         return c == '<' && '&lt;' ||
41876          c == '>' && '&gt;' ||
41877          c == '&' && '&amp;' ||
41878          c == '"' && '&quot;' ||
41879          '&#'+c.charCodeAt()+';'
41880 }
41881
41882
41883 copy$1(NodeType,Node$2);
41884 copy$1(NodeType,Node$2.prototype);
41885
41886 /**
41887  * @param callback return true for continue,false for break
41888  * @return boolean true: break visit;
41889  */
41890 function _visitNode(node,callback){
41891         if(callback(node)){
41892                 return true;
41893         }
41894         if(node = node.firstChild){
41895                 do{
41896                         if(_visitNode(node,callback)){return true}
41897         }while(node=node.nextSibling)
41898     }
41899 }
41900
41901
41902
41903 function Document(){
41904 }
41905 function _onAddAttribute(doc,el,newAttr){
41906         doc && doc._inc++;
41907         var ns = newAttr.namespaceURI;
41908         if(ns == 'http://www.w3.org/2000/xmlns/'){
41909                 //update namespace
41910                 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
41911         }
41912 }
41913 function _onRemoveAttribute(doc,el,newAttr,remove){
41914         doc && doc._inc++;
41915         var ns = newAttr.namespaceURI;
41916         if(ns == 'http://www.w3.org/2000/xmlns/'){
41917                 //update namespace
41918                 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
41919         }
41920 }
41921 function _onUpdateChild(doc,el,newChild){
41922         if(doc && doc._inc){
41923                 doc._inc++;
41924                 //update childNodes
41925                 var cs = el.childNodes;
41926                 if(newChild){
41927                         cs[cs.length++] = newChild;
41928                 }else{
41929                         //console.log(1)
41930                         var child = el.firstChild;
41931                         var i = 0;
41932                         while(child){
41933                                 cs[i++] = child;
41934                                 child =child.nextSibling;
41935                         }
41936                         cs.length = i;
41937                 }
41938         }
41939 }
41940
41941 /**
41942  * attributes;
41943  * children;
41944  * 
41945  * writeable properties:
41946  * nodeValue,Attr:value,CharacterData:data
41947  * prefix
41948  */
41949 function _removeChild(parentNode,child){
41950         var previous = child.previousSibling;
41951         var next = child.nextSibling;
41952         if(previous){
41953                 previous.nextSibling = next;
41954         }else{
41955                 parentNode.firstChild = next;
41956         }
41957         if(next){
41958                 next.previousSibling = previous;
41959         }else{
41960                 parentNode.lastChild = previous;
41961         }
41962         _onUpdateChild(parentNode.ownerDocument,parentNode);
41963         return child;
41964 }
41965 /**
41966  * preformance key(refChild == null)
41967  */
41968 function _insertBefore(parentNode,newChild,nextChild){
41969         var cp = newChild.parentNode;
41970         if(cp){
41971                 cp.removeChild(newChild);//remove and update
41972         }
41973         if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41974                 var newFirst = newChild.firstChild;
41975                 if (newFirst == null) {
41976                         return newChild;
41977                 }
41978                 var newLast = newChild.lastChild;
41979         }else{
41980                 newFirst = newLast = newChild;
41981         }
41982         var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
41983
41984         newFirst.previousSibling = pre;
41985         newLast.nextSibling = nextChild;
41986         
41987         
41988         if(pre){
41989                 pre.nextSibling = newFirst;
41990         }else{
41991                 parentNode.firstChild = newFirst;
41992         }
41993         if(nextChild == null){
41994                 parentNode.lastChild = newLast;
41995         }else{
41996                 nextChild.previousSibling = newLast;
41997         }
41998         do{
41999                 newFirst.parentNode = parentNode;
42000         }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
42001         _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
42002         //console.log(parentNode.lastChild.nextSibling == null)
42003         if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
42004                 newChild.firstChild = newChild.lastChild = null;
42005         }
42006         return newChild;
42007 }
42008 function _appendSingleChild(parentNode,newChild){
42009         var cp = newChild.parentNode;
42010         if(cp){
42011                 var pre = parentNode.lastChild;
42012                 cp.removeChild(newChild);//remove and update
42013                 var pre = parentNode.lastChild;
42014         }
42015         var pre = parentNode.lastChild;
42016         newChild.parentNode = parentNode;
42017         newChild.previousSibling = pre;
42018         newChild.nextSibling = null;
42019         if(pre){
42020                 pre.nextSibling = newChild;
42021         }else{
42022                 parentNode.firstChild = newChild;
42023         }
42024         parentNode.lastChild = newChild;
42025         _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
42026         return newChild;
42027         //console.log("__aa",parentNode.lastChild.nextSibling == null)
42028 }
42029 Document.prototype = {
42030         //implementation : null,
42031         nodeName :  '#document',
42032         nodeType :  DOCUMENT_NODE,
42033         doctype :  null,
42034         documentElement :  null,
42035         _inc : 1,
42036         
42037         insertBefore :  function(newChild, refChild){//raises 
42038                 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
42039                         var child = newChild.firstChild;
42040                         while(child){
42041                                 var next = child.nextSibling;
42042                                 this.insertBefore(child,refChild);
42043                                 child = next;
42044                         }
42045                         return newChild;
42046                 }
42047                 if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
42048                         this.documentElement = newChild;
42049                 }
42050                 
42051                 return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
42052         },
42053         removeChild :  function(oldChild){
42054                 if(this.documentElement == oldChild){
42055                         this.documentElement = null;
42056                 }
42057                 return _removeChild(this,oldChild);
42058         },
42059         // Introduced in DOM Level 2:
42060         importNode : function(importedNode,deep){
42061                 return importNode(this,importedNode,deep);
42062         },
42063         // Introduced in DOM Level 2:
42064         getElementById :        function(id){
42065                 var rtv = null;
42066                 _visitNode(this.documentElement,function(node){
42067                         if(node.nodeType == ELEMENT_NODE){
42068                                 if(node.getAttribute('id') == id){
42069                                         rtv = node;
42070                                         return true;
42071                                 }
42072                         }
42073                 });
42074                 return rtv;
42075         },
42076         
42077         //document factory method:
42078         createElement : function(tagName){
42079                 var node = new Element();
42080                 node.ownerDocument = this;
42081                 node.nodeName = tagName;
42082                 node.tagName = tagName;
42083                 node.childNodes = new NodeList();
42084                 var attrs       = node.attributes = new NamedNodeMap();
42085                 attrs._ownerElement = node;
42086                 return node;
42087         },
42088         createDocumentFragment :        function(){
42089                 var node = new DocumentFragment();
42090                 node.ownerDocument = this;
42091                 node.childNodes = new NodeList();
42092                 return node;
42093         },
42094         createTextNode :        function(data){
42095                 var node = new Text();
42096                 node.ownerDocument = this;
42097                 node.appendData(data);
42098                 return node;
42099         },
42100         createComment : function(data){
42101                 var node = new Comment();
42102                 node.ownerDocument = this;
42103                 node.appendData(data);
42104                 return node;
42105         },
42106         createCDATASection :    function(data){
42107                 var node = new CDATASection();
42108                 node.ownerDocument = this;
42109                 node.appendData(data);
42110                 return node;
42111         },
42112         createProcessingInstruction :   function(target,data){
42113                 var node = new ProcessingInstruction();
42114                 node.ownerDocument = this;
42115                 node.tagName = node.target = target;
42116                 node.nodeValue= node.data = data;
42117                 return node;
42118         },
42119         createAttribute :       function(name){
42120                 var node = new Attr();
42121                 node.ownerDocument      = this;
42122                 node.name = name;
42123                 node.nodeName   = name;
42124                 node.localName = name;
42125                 node.specified = true;
42126                 return node;
42127         },
42128         createEntityReference : function(name){
42129                 var node = new EntityReference();
42130                 node.ownerDocument      = this;
42131                 node.nodeName   = name;
42132                 return node;
42133         },
42134         // Introduced in DOM Level 2:
42135         createElementNS :       function(namespaceURI,qualifiedName){
42136                 var node = new Element();
42137                 var pl = qualifiedName.split(':');
42138                 var attrs       = node.attributes = new NamedNodeMap();
42139                 node.childNodes = new NodeList();
42140                 node.ownerDocument = this;
42141                 node.nodeName = qualifiedName;
42142                 node.tagName = qualifiedName;
42143                 node.namespaceURI = namespaceURI;
42144                 if(pl.length == 2){
42145                         node.prefix = pl[0];
42146                         node.localName = pl[1];
42147                 }else{
42148                         //el.prefix = null;
42149                         node.localName = qualifiedName;
42150                 }
42151                 attrs._ownerElement = node;
42152                 return node;
42153         },
42154         // Introduced in DOM Level 2:
42155         createAttributeNS :     function(namespaceURI,qualifiedName){
42156                 var node = new Attr();
42157                 var pl = qualifiedName.split(':');
42158                 node.ownerDocument = this;
42159                 node.nodeName = qualifiedName;
42160                 node.name = qualifiedName;
42161                 node.namespaceURI = namespaceURI;
42162                 node.specified = true;
42163                 if(pl.length == 2){
42164                         node.prefix = pl[0];
42165                         node.localName = pl[1];
42166                 }else{
42167                         //el.prefix = null;
42168                         node.localName = qualifiedName;
42169                 }
42170                 return node;
42171         }
42172 };
42173 _extends(Document,Node$2);
42174
42175
42176 function Element() {
42177         this._nsMap = {};
42178 }
42179 Element.prototype = {
42180         nodeType : ELEMENT_NODE,
42181         hasAttribute : function(name){
42182                 return this.getAttributeNode(name)!=null;
42183         },
42184         getAttribute : function(name){
42185                 var attr = this.getAttributeNode(name);
42186                 return attr && attr.value || '';
42187         },
42188         getAttributeNode : function(name){
42189                 return this.attributes.getNamedItem(name);
42190         },
42191         setAttribute : function(name, value){
42192                 var attr = this.ownerDocument.createAttribute(name);
42193                 attr.value = attr.nodeValue = "" + value;
42194                 this.setAttributeNode(attr);
42195         },
42196         removeAttribute : function(name){
42197                 var attr = this.getAttributeNode(name);
42198                 attr && this.removeAttributeNode(attr);
42199         },
42200         
42201         //four real opeartion method
42202         appendChild:function(newChild){
42203                 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
42204                         return this.insertBefore(newChild,null);
42205                 }else{
42206                         return _appendSingleChild(this,newChild);
42207                 }
42208         },
42209         setAttributeNode : function(newAttr){
42210                 return this.attributes.setNamedItem(newAttr);
42211         },
42212         setAttributeNodeNS : function(newAttr){
42213                 return this.attributes.setNamedItemNS(newAttr);
42214         },
42215         removeAttributeNode : function(oldAttr){
42216                 //console.log(this == oldAttr.ownerElement)
42217                 return this.attributes.removeNamedItem(oldAttr.nodeName);
42218         },
42219         //get real attribute name,and remove it by removeAttributeNode
42220         removeAttributeNS : function(namespaceURI, localName){
42221                 var old = this.getAttributeNodeNS(namespaceURI, localName);
42222                 old && this.removeAttributeNode(old);
42223         },
42224         
42225         hasAttributeNS : function(namespaceURI, localName){
42226                 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
42227         },
42228         getAttributeNS : function(namespaceURI, localName){
42229                 var attr = this.getAttributeNodeNS(namespaceURI, localName);
42230                 return attr && attr.value || '';
42231         },
42232         setAttributeNS : function(namespaceURI, qualifiedName, value){
42233                 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
42234                 attr.value = attr.nodeValue = "" + value;
42235                 this.setAttributeNode(attr);
42236         },
42237         getAttributeNodeNS : function(namespaceURI, localName){
42238                 return this.attributes.getNamedItemNS(namespaceURI, localName);
42239         },
42240         
42241         getElementsByTagName : function(tagName){
42242                 return new LiveNodeList(this,function(base){
42243                         var ls = [];
42244                         _visitNode(base,function(node){
42245                                 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
42246                                         ls.push(node);
42247                                 }
42248                         });
42249                         return ls;
42250                 });
42251         },
42252         getElementsByTagNameNS : function(namespaceURI, localName){
42253                 return new LiveNodeList(this,function(base){
42254                         var ls = [];
42255                         _visitNode(base,function(node){
42256                                 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
42257                                         ls.push(node);
42258                                 }
42259                         });
42260                         return ls;
42261                         
42262                 });
42263         }
42264 };
42265 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
42266 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
42267
42268
42269 _extends(Element,Node$2);
42270 function Attr() {
42271 }
42272 Attr.prototype.nodeType = ATTRIBUTE_NODE;
42273 _extends(Attr,Node$2);
42274
42275
42276 function CharacterData() {
42277 }
42278 CharacterData.prototype = {
42279         data : '',
42280         substringData : function(offset, count) {
42281                 return this.data.substring(offset, offset+count);
42282         },
42283         appendData: function(text) {
42284                 text = this.data+text;
42285                 this.nodeValue = this.data = text;
42286                 this.length = text.length;
42287         },
42288         insertData: function(offset,text) {
42289                 this.replaceData(offset,0,text);
42290         
42291         },
42292         appendChild:function(newChild){
42293                 throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
42294         },
42295         deleteData: function(offset, count) {
42296                 this.replaceData(offset,count,"");
42297         },
42298         replaceData: function(offset, count, text) {
42299                 var start = this.data.substring(0,offset);
42300                 var end = this.data.substring(offset+count);
42301                 text = start + text + end;
42302                 this.nodeValue = this.data = text;
42303                 this.length = text.length;
42304         }
42305 };
42306 _extends(CharacterData,Node$2);
42307 function Text() {
42308 }
42309 Text.prototype = {
42310         nodeName : "#text",
42311         nodeType : TEXT_NODE,
42312         splitText : function(offset) {
42313                 var text = this.data;
42314                 var newText = text.substring(offset);
42315                 text = text.substring(0, offset);
42316                 this.data = this.nodeValue = text;
42317                 this.length = text.length;
42318                 var newNode = this.ownerDocument.createTextNode(newText);
42319                 if(this.parentNode){
42320                         this.parentNode.insertBefore(newNode, this.nextSibling);
42321                 }
42322                 return newNode;
42323         }
42324 };
42325 _extends(Text,CharacterData);
42326 function Comment() {
42327 }
42328 Comment.prototype = {
42329         nodeName : "#comment",
42330         nodeType : COMMENT_NODE
42331 };
42332 _extends(Comment,CharacterData);
42333
42334 function CDATASection() {
42335 }
42336 CDATASection.prototype = {
42337         nodeName : "#cdata-section",
42338         nodeType : CDATA_SECTION_NODE
42339 };
42340 _extends(CDATASection,CharacterData);
42341
42342
42343 function DocumentType() {
42344 }
42345 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
42346 _extends(DocumentType,Node$2);
42347
42348 function Notation() {
42349 }
42350 Notation.prototype.nodeType = NOTATION_NODE;
42351 _extends(Notation,Node$2);
42352
42353 function Entity() {
42354 }
42355 Entity.prototype.nodeType = ENTITY_NODE;
42356 _extends(Entity,Node$2);
42357
42358 function EntityReference() {
42359 }
42360 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
42361 _extends(EntityReference,Node$2);
42362
42363 function DocumentFragment() {
42364 }
42365 DocumentFragment.prototype.nodeName =   "#document-fragment";
42366 DocumentFragment.prototype.nodeType =   DOCUMENT_FRAGMENT_NODE;
42367 _extends(DocumentFragment,Node$2);
42368
42369
42370 function ProcessingInstruction() {
42371 }
42372 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
42373 _extends(ProcessingInstruction,Node$2);
42374 function XMLSerializer$1(){}
42375 XMLSerializer$1.prototype.serializeToString = function(node,isHtml,nodeFilter){
42376         return nodeSerializeToString.call(node,isHtml,nodeFilter);
42377 };
42378 Node$2.prototype.toString = nodeSerializeToString;
42379 function nodeSerializeToString(isHtml,nodeFilter){
42380         var buf = [];
42381         var refNode = this.nodeType == 9?this.documentElement:this;
42382         var prefix = refNode.prefix;
42383         var uri = refNode.namespaceURI;
42384         
42385         if(uri && prefix == null){
42386                 //console.log(prefix)
42387                 var prefix = refNode.lookupPrefix(uri);
42388                 if(prefix == null){
42389                         //isHTML = true;
42390                         var visibleNamespaces=[
42391                         {namespace:uri,prefix:null}
42392                         //{namespace:uri,prefix:''}
42393                         ];
42394                 }
42395         }
42396         serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
42397         //console.log('###',this.nodeType,uri,prefix,buf.join(''))
42398         return buf.join('');
42399 }
42400 function needNamespaceDefine(node,isHTML, visibleNamespaces) {
42401         var prefix = node.prefix||'';
42402         var uri = node.namespaceURI;
42403         if (!prefix && !uri){
42404                 return false;
42405         }
42406         if (prefix === "xml" && uri === "http://www.w3.org/XML/1998/namespace" 
42407                 || uri == 'http://www.w3.org/2000/xmlns/'){
42408                 return false;
42409         }
42410         
42411         var i = visibleNamespaces.length; 
42412         //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces)
42413         while (i--) {
42414                 var ns = visibleNamespaces[i];
42415                 // get namespace prefix
42416                 //console.log(node.nodeType,node.tagName,ns.prefix,prefix)
42417                 if (ns.prefix == prefix){
42418                         return ns.namespace != uri;
42419                 }
42420         }
42421         //console.log(isHTML,uri,prefix=='')
42422         //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){
42423         //      return false;
42424         //}
42425         //node.flag = '11111'
42426         //console.error(3,true,node.flag,node.prefix,node.namespaceURI)
42427         return true;
42428 }
42429 function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
42430         if(nodeFilter){
42431                 node = nodeFilter(node);
42432                 if(node){
42433                         if(typeof node == 'string'){
42434                                 buf.push(node);
42435                                 return;
42436                         }
42437                 }else{
42438                         return;
42439                 }
42440                 //buf.sort.apply(attrs, attributeSorter);
42441         }
42442         switch(node.nodeType){
42443         case ELEMENT_NODE:
42444                 if (!visibleNamespaces) visibleNamespaces = [];
42445                 var startVisibleNamespaces = visibleNamespaces.length;
42446                 var attrs = node.attributes;
42447                 var len = attrs.length;
42448                 var child = node.firstChild;
42449                 var nodeName = node.tagName;
42450                 
42451                 isHTML =  (htmlns === node.namespaceURI) ||isHTML; 
42452                 buf.push('<',nodeName);
42453                 
42454                 
42455                 
42456                 for(var i=0;i<len;i++){
42457                         // add namespaces for attributes
42458                         var attr = attrs.item(i);
42459                         if (attr.prefix == 'xmlns') {
42460                                 visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
42461                         }else if(attr.nodeName == 'xmlns'){
42462                                 visibleNamespaces.push({ prefix: '', namespace: attr.value });
42463                         }
42464                 }
42465                 for(var i=0;i<len;i++){
42466                         var attr = attrs.item(i);
42467                         if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
42468                                 var prefix = attr.prefix||'';
42469                                 var uri = attr.namespaceURI;
42470                                 var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42471                                 buf.push(ns, '="' , uri , '"');
42472                                 visibleNamespaces.push({ prefix: prefix, namespace:uri });
42473                         }
42474                         serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
42475                 }
42476                 // add namespace for current node               
42477                 if (needNamespaceDefine(node,isHTML, visibleNamespaces)) {
42478                         var prefix = node.prefix||'';
42479                         var uri = node.namespaceURI;
42480                         var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42481                         buf.push(ns, '="' , uri , '"');
42482                         visibleNamespaces.push({ prefix: prefix, namespace:uri });
42483                 }
42484                 
42485                 if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
42486                         buf.push('>');
42487                         //if is cdata child node
42488                         if(isHTML && /^script$/i.test(nodeName)){
42489                                 while(child){
42490                                         if(child.data){
42491                                                 buf.push(child.data);
42492                                         }else{
42493                                                 serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42494                                         }
42495                                         child = child.nextSibling;
42496                                 }
42497                         }else
42498                         {
42499                                 while(child){
42500                                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42501                                         child = child.nextSibling;
42502                                 }
42503                         }
42504                         buf.push('</',nodeName,'>');
42505                 }else{
42506                         buf.push('/>');
42507                 }
42508                 // remove added visible namespaces
42509                 //visibleNamespaces.length = startVisibleNamespaces;
42510                 return;
42511         case DOCUMENT_NODE:
42512         case DOCUMENT_FRAGMENT_NODE:
42513                 var child = node.firstChild;
42514                 while(child){
42515                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42516                         child = child.nextSibling;
42517                 }
42518                 return;
42519         case ATTRIBUTE_NODE:
42520                 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
42521         case TEXT_NODE:
42522                 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
42523         case CDATA_SECTION_NODE:
42524                 return buf.push( '<![CDATA[',node.data,']]>');
42525         case COMMENT_NODE:
42526                 return buf.push( "<!--",node.data,"-->");
42527         case DOCUMENT_TYPE_NODE:
42528                 var pubid = node.publicId;
42529                 var sysid = node.systemId;
42530                 buf.push('<!DOCTYPE ',node.name);
42531                 if(pubid){
42532                         buf.push(' PUBLIC "',pubid);
42533                         if (sysid && sysid!='.') {
42534                                 buf.push( '" "',sysid);
42535                         }
42536                         buf.push('">');
42537                 }else if(sysid && sysid!='.'){
42538                         buf.push(' SYSTEM "',sysid,'">');
42539                 }else{
42540                         var sub = node.internalSubset;
42541                         if(sub){
42542                                 buf.push(" [",sub,"]");
42543                         }
42544                         buf.push(">");
42545                 }
42546                 return;
42547         case PROCESSING_INSTRUCTION_NODE:
42548                 return buf.push( "<?",node.target," ",node.data,"?>");
42549         case ENTITY_REFERENCE_NODE:
42550                 return buf.push( '&',node.nodeName,';');
42551         //case ENTITY_NODE:
42552         //case NOTATION_NODE:
42553         default:
42554                 buf.push('??',node.nodeName);
42555         }
42556 }
42557 function importNode(doc,node,deep){
42558         var node2;
42559         switch (node.nodeType) {
42560         case ELEMENT_NODE:
42561                 node2 = node.cloneNode(false);
42562                 node2.ownerDocument = doc;
42563                 //var attrs = node2.attributes;
42564                 //var len = attrs.length;
42565                 //for(var i=0;i<len;i++){
42566                         //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
42567                 //}
42568         case DOCUMENT_FRAGMENT_NODE:
42569                 break;
42570         case ATTRIBUTE_NODE:
42571                 deep = true;
42572                 break;
42573         //case ENTITY_REFERENCE_NODE:
42574         //case PROCESSING_INSTRUCTION_NODE:
42575         ////case TEXT_NODE:
42576         //case CDATA_SECTION_NODE:
42577         //case COMMENT_NODE:
42578         //      deep = false;
42579         //      break;
42580         //case DOCUMENT_NODE:
42581         //case DOCUMENT_TYPE_NODE:
42582         //cannot be imported.
42583         //case ENTITY_NODE:
42584         //case NOTATION_NODE:
42585         //can not hit in level3
42586         //default:throw e;
42587         }
42588         if(!node2){
42589                 node2 = node.cloneNode(false);//false
42590         }
42591         node2.ownerDocument = doc;
42592         node2.parentNode = null;
42593         if(deep){
42594                 var child = node.firstChild;
42595                 while(child){
42596                         node2.appendChild(importNode(doc,child,deep));
42597                         child = child.nextSibling;
42598                 }
42599         }
42600         return node2;
42601 }
42602 //
42603 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
42604 //                                      attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
42605 function cloneNode(doc,node,deep){
42606         var node2 = new node.constructor();
42607         for(var n in node){
42608                 var v = node[n];
42609                 if(typeof v != 'object' ){
42610                         if(v != node2[n]){
42611                                 node2[n] = v;
42612                         }
42613                 }
42614         }
42615         if(node.childNodes){
42616                 node2.childNodes = new NodeList();
42617         }
42618         node2.ownerDocument = doc;
42619         switch (node2.nodeType) {
42620         case ELEMENT_NODE:
42621                 var attrs       = node.attributes;
42622                 var attrs2      = node2.attributes = new NamedNodeMap();
42623                 var len = attrs.length;
42624                 attrs2._ownerElement = node2;
42625                 for(var i=0;i<len;i++){
42626                         node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
42627                 }
42628                 break;;
42629         case ATTRIBUTE_NODE:
42630                 deep = true;
42631         }
42632         if(deep){
42633                 var child = node.firstChild;
42634                 while(child){
42635                         node2.appendChild(cloneNode(doc,child,deep));
42636                         child = child.nextSibling;
42637                 }
42638         }
42639         return node2;
42640 }
42641
42642 function __set__(object,key,value){
42643         object[key] = value;
42644 }
42645 //do dynamic
42646 try{
42647         if(Object.defineProperty){
42648                 Object.defineProperty(LiveNodeList.prototype,'length',{
42649                         get:function(){
42650                                 _updateLiveList(this);
42651                                 return this.$$length;
42652                         }
42653                 });
42654                 Object.defineProperty(Node$2.prototype,'textContent',{
42655                         get:function(){
42656                                 return getTextContent(this);
42657                         },
42658                         set:function(data){
42659                                 switch(this.nodeType){
42660                                 case ELEMENT_NODE:
42661                                 case DOCUMENT_FRAGMENT_NODE:
42662                                         while(this.firstChild){
42663                                                 this.removeChild(this.firstChild);
42664                                         }
42665                                         if(data || String(data)){
42666                                                 this.appendChild(this.ownerDocument.createTextNode(data));
42667                                         }
42668                                         break;
42669                                 default:
42670                                         //TODO:
42671                                         this.data = data;
42672                                         this.value = data;
42673                                         this.nodeValue = data;
42674                                 }
42675                         }
42676                 });
42677                 
42678                 function getTextContent(node){
42679                         switch(node.nodeType){
42680                         case ELEMENT_NODE:
42681                         case DOCUMENT_FRAGMENT_NODE:
42682                                 var buf = [];
42683                                 node = node.firstChild;
42684                                 while(node){
42685                                         if(node.nodeType!==7 && node.nodeType !==8){
42686                                                 buf.push(getTextContent(node));
42687                                         }
42688                                         node = node.nextSibling;
42689                                 }
42690                                 return buf.join('');
42691                         default:
42692                                 return node.nodeValue;
42693                         }
42694                 }
42695                 __set__ = function(object,key,value){
42696                         //console.log(value)
42697                         object['$$'+key] = value;
42698                 };
42699         }
42700 }catch(e){//ie8
42701 }
42702
42703 //if(typeof require == 'function'){
42704         var DOMImplementation_1 = DOMImplementation;
42705         var XMLSerializer_1 = XMLSerializer$1;
42706 //}
42707
42708 var dom = {
42709         DOMImplementation: DOMImplementation_1,
42710         XMLSerializer: XMLSerializer_1
42711 };
42712
42713 var domParser = createCommonjsModule(function (module, exports) {
42714 function DOMParser(options){
42715         this.options = options ||{locator:{}};
42716         
42717 }
42718 DOMParser.prototype.parseFromString = function(source,mimeType){
42719         var options = this.options;
42720         var sax$$1 =  new XMLReader();
42721         var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
42722         var errorHandler = options.errorHandler;
42723         var locator = options.locator;
42724         var defaultNSMap = options.xmlns||{};
42725         var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
42726         if(locator){
42727                 domBuilder.setDocumentLocator(locator);
42728         }
42729         
42730         sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
42731         sax$$1.domBuilder = options.domBuilder || domBuilder;
42732         if(/\/x?html?$/.test(mimeType)){
42733                 entityMap.nbsp = '\xa0';
42734                 entityMap.copy = '\xa9';
42735                 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
42736         }
42737         defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
42738         if(source){
42739                 sax$$1.parse(source,defaultNSMap,entityMap);
42740         }else{
42741                 sax$$1.errorHandler.error("invalid doc source");
42742         }
42743         return domBuilder.doc;
42744 };
42745 function buildErrorHandler(errorImpl,domBuilder,locator){
42746         if(!errorImpl){
42747                 if(domBuilder instanceof DOMHandler){
42748                         return domBuilder;
42749                 }
42750                 errorImpl = domBuilder ;
42751         }
42752         var errorHandler = {};
42753         var isCallback = errorImpl instanceof Function;
42754         locator = locator||{};
42755         function build(key){
42756                 var fn = errorImpl[key];
42757                 if(!fn && isCallback){
42758                         fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
42759                 }
42760                 errorHandler[key] = fn && function(msg){
42761                         fn('[xmldom '+key+']\t'+msg+_locator(locator));
42762                 }||function(){};
42763         }
42764         build('warning');
42765         build('error');
42766         build('fatalError');
42767         return errorHandler;
42768 }
42769
42770 //console.log('#\n\n\n\n\n\n\n####')
42771 /**
42772  * +ContentHandler+ErrorHandler
42773  * +LexicalHandler+EntityResolver2
42774  * -DeclHandler-DTDHandler 
42775  * 
42776  * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
42777  * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
42778  * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
42779  */
42780 function DOMHandler() {
42781     this.cdata = false;
42782 }
42783 function position(locator,node){
42784         node.lineNumber = locator.lineNumber;
42785         node.columnNumber = locator.columnNumber;
42786 }
42787 /**
42788  * @see org.xml.sax.ContentHandler#startDocument
42789  * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
42790  */ 
42791 DOMHandler.prototype = {
42792         startDocument : function() {
42793         this.doc = new DOMImplementation().createDocument(null, null, null);
42794         if (this.locator) {
42795                 this.doc.documentURI = this.locator.systemId;
42796         }
42797         },
42798         startElement:function(namespaceURI, localName, qName, attrs) {
42799                 var doc = this.doc;
42800             var el = doc.createElementNS(namespaceURI, qName||localName);
42801             var len = attrs.length;
42802             appendElement(this, el);
42803             this.currentElement = el;
42804             
42805                 this.locator && position(this.locator,el);
42806             for (var i = 0 ; i < len; i++) {
42807                 var namespaceURI = attrs.getURI(i);
42808                 var value = attrs.getValue(i);
42809                 var qName = attrs.getQName(i);
42810                         var attr = doc.createAttributeNS(namespaceURI, qName);
42811                         this.locator &&position(attrs.getLocator(i),attr);
42812                         attr.value = attr.nodeValue = value;
42813                         el.setAttributeNode(attr);
42814             }
42815         },
42816         endElement:function(namespaceURI, localName, qName) {
42817                 var current = this.currentElement;
42818                 var tagName = current.tagName;
42819                 this.currentElement = current.parentNode;
42820         },
42821         startPrefixMapping:function(prefix, uri) {
42822         },
42823         endPrefixMapping:function(prefix) {
42824         },
42825         processingInstruction:function(target, data) {
42826             var ins = this.doc.createProcessingInstruction(target, data);
42827             this.locator && position(this.locator,ins);
42828             appendElement(this, ins);
42829         },
42830         ignorableWhitespace:function(ch, start, length) {
42831         },
42832         characters:function(chars, start, length) {
42833                 chars = _toString.apply(this,arguments);
42834                 //console.log(chars)
42835                 if(chars){
42836                         if (this.cdata) {
42837                                 var charNode = this.doc.createCDATASection(chars);
42838                         } else {
42839                                 var charNode = this.doc.createTextNode(chars);
42840                         }
42841                         if(this.currentElement){
42842                                 this.currentElement.appendChild(charNode);
42843                         }else if(/^\s*$/.test(chars)){
42844                                 this.doc.appendChild(charNode);
42845                                 //process xml
42846                         }
42847                         this.locator && position(this.locator,charNode);
42848                 }
42849         },
42850         skippedEntity:function(name) {
42851         },
42852         endDocument:function() {
42853                 this.doc.normalize();
42854         },
42855         setDocumentLocator:function (locator) {
42856             if(this.locator = locator){// && !('lineNumber' in locator)){
42857                 locator.lineNumber = 0;
42858             }
42859         },
42860         //LexicalHandler
42861         comment:function(chars, start, length) {
42862                 chars = _toString.apply(this,arguments);
42863             var comm = this.doc.createComment(chars);
42864             this.locator && position(this.locator,comm);
42865             appendElement(this, comm);
42866         },
42867         
42868         startCDATA:function() {
42869             //used in characters() methods
42870             this.cdata = true;
42871         },
42872         endCDATA:function() {
42873             this.cdata = false;
42874         },
42875         
42876         startDTD:function(name, publicId, systemId) {
42877                 var impl = this.doc.implementation;
42878             if (impl && impl.createDocumentType) {
42879                 var dt = impl.createDocumentType(name, publicId, systemId);
42880                 this.locator && position(this.locator,dt);
42881                 appendElement(this, dt);
42882             }
42883         },
42884         /**
42885          * @see org.xml.sax.ErrorHandler
42886          * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
42887          */
42888         warning:function(error) {
42889                 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
42890         },
42891         error:function(error) {
42892                 console.error('[xmldom error]\t'+error,_locator(this.locator));
42893         },
42894         fatalError:function(error) {
42895                 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
42896             throw error;
42897         }
42898 };
42899 function _locator(l){
42900         if(l){
42901                 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
42902         }
42903 }
42904 function _toString(chars,start,length){
42905         if(typeof chars == 'string'){
42906                 return chars.substr(start,length)
42907         }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
42908                 if(chars.length >= start+length || start){
42909                         return new java.lang.String(chars,start,length)+'';
42910                 }
42911                 return chars;
42912         }
42913 }
42914
42915 /*
42916  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
42917  * used method of org.xml.sax.ext.LexicalHandler:
42918  *  #comment(chars, start, length)
42919  *  #startCDATA()
42920  *  #endCDATA()
42921  *  #startDTD(name, publicId, systemId)
42922  *
42923  *
42924  * IGNORED method of org.xml.sax.ext.LexicalHandler:
42925  *  #endDTD()
42926  *  #startEntity(name)
42927  *  #endEntity(name)
42928  *
42929  *
42930  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
42931  * IGNORED method of org.xml.sax.ext.DeclHandler
42932  *      #attributeDecl(eName, aName, type, mode, value)
42933  *  #elementDecl(name, model)
42934  *  #externalEntityDecl(name, publicId, systemId)
42935  *  #internalEntityDecl(name, value)
42936  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
42937  * IGNORED method of org.xml.sax.EntityResolver2
42938  *  #resolveEntity(String name,String publicId,String baseURI,String systemId)
42939  *  #resolveEntity(publicId, systemId)
42940  *  #getExternalSubset(name, baseURI)
42941  * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
42942  * IGNORED method of org.xml.sax.DTDHandler
42943  *  #notationDecl(name, publicId, systemId) {};
42944  *  #unparsedEntityDecl(name, publicId, systemId, notationName) {};
42945  */
42946 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
42947         DOMHandler.prototype[key] = function(){return null};
42948 });
42949
42950 /* 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 */
42951 function appendElement (hander,node) {
42952     if (!hander.currentElement) {
42953         hander.doc.appendChild(node);
42954     } else {
42955         hander.currentElement.appendChild(node);
42956     }
42957 }//appendChild and setAttributeNS are preformance key
42958
42959 //if(typeof require == 'function'){
42960         var XMLReader = sax.XMLReader;
42961         var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
42962         exports.XMLSerializer = dom.XMLSerializer ;
42963         exports.DOMParser = DOMParser;
42964 //}
42965 });
42966
42967 var togeojson = createCommonjsModule(function (module, exports) {
42968 var toGeoJSON = (function() {
42969     'use strict';
42970
42971     var removeSpace = /\s*/g,
42972         trimSpace = /^\s*|\s*$/g,
42973         splitSpace = /\s+/;
42974     // generate a short, numeric hash of a string
42975     function okhash(x) {
42976         if (!x || !x.length) return 0;
42977         for (var i = 0, h = 0; i < x.length; i++) {
42978             h = ((h << 5) - h) + x.charCodeAt(i) | 0;
42979         } return h;
42980     }
42981     // all Y children of X
42982     function get(x, y) { return x.getElementsByTagName(y); }
42983     function attr(x, y) { return x.getAttribute(y); }
42984     function attrf(x, y) { return parseFloat(attr(x, y)); }
42985     // one Y child of X, if any, otherwise null
42986     function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
42987     // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
42988     function norm(el) { if (el.normalize) { el.normalize(); } return el; }
42989     // cast array x into numbers
42990     function numarray(x) {
42991         for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
42992         return o;
42993     }
42994     // get the content of a text node, if any
42995     function nodeVal(x) {
42996         if (x) { norm(x); }
42997         return (x && x.textContent) || '';
42998     }
42999     // get the contents of multiple text nodes, if present
43000     function getMulti(x, ys) {
43001         var o = {}, n, k;
43002         for (k = 0; k < ys.length; k++) {
43003             n = get1(x, ys[k]);
43004             if (n) o[ys[k]] = nodeVal(n);
43005         }
43006         return o;
43007     }
43008     // add properties of Y to X, overwriting if present in both
43009     function extend(x, y) { for (var k in y) x[k] = y[k]; }
43010     // get one coordinate from a coordinate array, if any
43011     function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
43012     // get all coordinates from a coordinate array as [[],[]]
43013     function coord(v) {
43014         var coords = v.replace(trimSpace, '').split(splitSpace),
43015             o = [];
43016         for (var i = 0; i < coords.length; i++) {
43017             o.push(coord1(coords[i]));
43018         }
43019         return o;
43020     }
43021     function coordPair(x) {
43022         var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
43023             ele = get1(x, 'ele'),
43024             // handle namespaced attribute in browser
43025             heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
43026             time = get1(x, 'time'),
43027             e;
43028         if (ele) {
43029             e = parseFloat(nodeVal(ele));
43030             if (!isNaN(e)) {
43031                 ll.push(e);
43032             }
43033         }
43034         return {
43035             coordinates: ll,
43036             time: time ? nodeVal(time) : null,
43037             heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
43038         };
43039     }
43040
43041     // create a new feature collection parent object
43042     function fc() {
43043         return {
43044             type: 'FeatureCollection',
43045             features: []
43046         };
43047     }
43048
43049     var serializer;
43050     if (typeof XMLSerializer !== 'undefined') {
43051         /* istanbul ignore next */
43052         serializer = new XMLSerializer();
43053     // only require xmldom in a node environment
43054     } else if ('object' === 'object' && typeof process === 'object' && !process.browser) {
43055         serializer = new (domParser.XMLSerializer)();
43056     }
43057     function xml2str(str) {
43058         // IE9 will create a new XMLSerializer but it'll crash immediately.
43059         // This line is ignored because we don't run coverage tests in IE9
43060         /* istanbul ignore next */
43061         if (str.xml !== undefined) return str.xml;
43062         return serializer.serializeToString(str);
43063     }
43064
43065     var t = {
43066         kml: function(doc) {
43067
43068             var gj = fc(),
43069                 // styleindex keeps track of hashed styles in order to match features
43070                 styleIndex = {}, styleByHash = {},
43071                 // stylemapindex keeps track of style maps to expose in properties
43072                 styleMapIndex = {},
43073                 // atomic geospatial types supported by KML - MultiGeometry is
43074                 // handled separately
43075                 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
43076                 // all root placemarks in the file
43077                 placemarks = get(doc, 'Placemark'),
43078                 styles = get(doc, 'Style'),
43079                 styleMaps = get(doc, 'StyleMap');
43080
43081             for (var k = 0; k < styles.length; k++) {
43082                 var hash = okhash(xml2str(styles[k])).toString(16);
43083                 styleIndex['#' + attr(styles[k], 'id')] = hash;
43084                 styleByHash[hash] = styles[k];
43085             }
43086             for (var l = 0; l < styleMaps.length; l++) {
43087                 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
43088                 var pairs = get(styleMaps[l], 'Pair');
43089                 var pairsMap = {};
43090                 for (var m = 0; m < pairs.length; m++) {
43091                     pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
43092                 }
43093                 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
43094
43095             }
43096             for (var j = 0; j < placemarks.length; j++) {
43097                 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
43098             }
43099             function kmlColor(v) {
43100                 var color, opacity;
43101                 v = v || '';
43102                 if (v.substr(0, 1) === '#') { v = v.substr(1); }
43103                 if (v.length === 6 || v.length === 3) { color = v; }
43104                 if (v.length === 8) {
43105                     opacity = parseInt(v.substr(0, 2), 16) / 255;
43106                     color = '#' + v.substr(6, 2) +
43107                         v.substr(4, 2) +
43108                         v.substr(2, 2);
43109                 }
43110                 return [color, isNaN(opacity) ? undefined : opacity];
43111             }
43112             function gxCoord(v) { return numarray(v.split(' ')); }
43113             function gxCoords(root) {
43114                 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
43115                 if (elems.length === 0) elems = get(root, 'gx:coord');
43116                 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
43117                 var timeElems = get(root, 'when');
43118                 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
43119                 return {
43120                     coords: coords,
43121                     times: times
43122                 };
43123             }
43124             function getGeometry(root) {
43125                 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
43126                 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
43127                 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
43128                 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
43129                 for (i = 0; i < geotypes.length; i++) {
43130                     geomNodes = get(root, geotypes[i]);
43131                     if (geomNodes) {
43132                         for (j = 0; j < geomNodes.length; j++) {
43133                             geomNode = geomNodes[j];
43134                             if (geotypes[i] === 'Point') {
43135                                 geoms.push({
43136                                     type: 'Point',
43137                                     coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
43138                                 });
43139                             } else if (geotypes[i] === 'LineString') {
43140                                 geoms.push({
43141                                     type: 'LineString',
43142                                     coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
43143                                 });
43144                             } else if (geotypes[i] === 'Polygon') {
43145                                 var rings = get(geomNode, 'LinearRing'),
43146                                     coords = [];
43147                                 for (k = 0; k < rings.length; k++) {
43148                                     coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
43149                                 }
43150                                 geoms.push({
43151                                     type: 'Polygon',
43152                                     coordinates: coords
43153                                 });
43154                             } else if (geotypes[i] === 'Track' ||
43155                                 geotypes[i] === 'gx:Track') {
43156                                 var track = gxCoords(geomNode);
43157                                 geoms.push({
43158                                     type: 'LineString',
43159                                     coordinates: track.coords
43160                                 });
43161                                 if (track.times.length) coordTimes.push(track.times);
43162                             }
43163                         }
43164                     }
43165                 }
43166                 return {
43167                     geoms: geoms,
43168                     coordTimes: coordTimes
43169                 };
43170             }
43171             function getPlacemark(root) {
43172                 var geomsAndTimes = getGeometry(root), i, properties = {},
43173                     name = nodeVal(get1(root, 'name')),
43174                     address = nodeVal(get1(root, 'address')),
43175                     styleUrl = nodeVal(get1(root, 'styleUrl')),
43176                     description = nodeVal(get1(root, 'description')),
43177                     timeSpan = get1(root, 'TimeSpan'),
43178                     timeStamp = get1(root, 'TimeStamp'),
43179                     extendedData = get1(root, 'ExtendedData'),
43180                     lineStyle = get1(root, 'LineStyle'),
43181                     polyStyle = get1(root, 'PolyStyle'),
43182                     visibility = get1(root, 'visibility');
43183
43184                 if (!geomsAndTimes.geoms.length) return [];
43185                 if (name) properties.name = name;
43186                 if (address) properties.address = address;
43187                 if (styleUrl) {
43188                     if (styleUrl[0] !== '#') {
43189                         styleUrl = '#' + styleUrl;
43190                     }
43191
43192                     properties.styleUrl = styleUrl;
43193                     if (styleIndex[styleUrl]) {
43194                         properties.styleHash = styleIndex[styleUrl];
43195                     }
43196                     if (styleMapIndex[styleUrl]) {
43197                         properties.styleMapHash = styleMapIndex[styleUrl];
43198                         properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
43199                     }
43200                     // Try to populate the lineStyle or polyStyle since we got the style hash
43201                     var style = styleByHash[properties.styleHash];
43202                     if (style) {
43203                         if (!lineStyle) lineStyle = get1(style, 'LineStyle');
43204                         if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
43205                     }
43206                 }
43207                 if (description) properties.description = description;
43208                 if (timeSpan) {
43209                     var begin = nodeVal(get1(timeSpan, 'begin'));
43210                     var end = nodeVal(get1(timeSpan, 'end'));
43211                     properties.timespan = { begin: begin, end: end };
43212                 }
43213                 if (timeStamp) {
43214                     properties.timestamp = nodeVal(get1(timeStamp, 'when'));
43215                 }
43216                 if (lineStyle) {
43217                     var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
43218                         color = linestyles[0],
43219                         opacity = linestyles[1],
43220                         width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43221                     if (color) properties.stroke = color;
43222                     if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
43223                     if (!isNaN(width)) properties['stroke-width'] = width;
43224                 }
43225                 if (polyStyle) {
43226                     var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
43227                         pcolor = polystyles[0],
43228                         popacity = polystyles[1],
43229                         fill = nodeVal(get1(polyStyle, 'fill')),
43230                         outline = nodeVal(get1(polyStyle, 'outline'));
43231                     if (pcolor) properties.fill = pcolor;
43232                     if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
43233                     if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
43234                     if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
43235                 }
43236                 if (extendedData) {
43237                     var datas = get(extendedData, 'Data'),
43238                         simpleDatas = get(extendedData, 'SimpleData');
43239
43240                     for (i = 0; i < datas.length; i++) {
43241                         properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
43242                     }
43243                     for (i = 0; i < simpleDatas.length; i++) {
43244                         properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
43245                     }
43246                 }
43247                 if (visibility) {
43248                     properties.visibility = nodeVal(visibility);
43249                 }
43250                 if (geomsAndTimes.coordTimes.length) {
43251                     properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
43252                         geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
43253                 }
43254                 var feature = {
43255                     type: 'Feature',
43256                     geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
43257                         type: 'GeometryCollection',
43258                         geometries: geomsAndTimes.geoms
43259                     },
43260                     properties: properties
43261                 };
43262                 if (attr(root, 'id')) feature.id = attr(root, 'id');
43263                 return [feature];
43264             }
43265             return gj;
43266         },
43267         gpx: function(doc) {
43268             var i,
43269                 tracks = get(doc, 'trk'),
43270                 routes = get(doc, 'rte'),
43271                 waypoints = get(doc, 'wpt'),
43272                 // a feature collection
43273                 gj = fc(),
43274                 feature;
43275             for (i = 0; i < tracks.length; i++) {
43276                 feature = getTrack(tracks[i]);
43277                 if (feature) gj.features.push(feature);
43278             }
43279             for (i = 0; i < routes.length; i++) {
43280                 feature = getRoute(routes[i]);
43281                 if (feature) gj.features.push(feature);
43282             }
43283             for (i = 0; i < waypoints.length; i++) {
43284                 gj.features.push(getPoint(waypoints[i]));
43285             }
43286             function getPoints(node, pointname) {
43287                 var pts = get(node, pointname),
43288                     line = [],
43289                     times = [],
43290                     heartRates = [],
43291                     l = pts.length;
43292                 if (l < 2) return {};  // Invalid line in GeoJSON
43293                 for (var i = 0; i < l; i++) {
43294                     var c = coordPair(pts[i]);
43295                     line.push(c.coordinates);
43296                     if (c.time) times.push(c.time);
43297                     if (c.heartRate) heartRates.push(c.heartRate);
43298                 }
43299                 return {
43300                     line: line,
43301                     times: times,
43302                     heartRates: heartRates
43303                 };
43304             }
43305             function getTrack(node) {
43306                 var segments = get(node, 'trkseg'),
43307                     track = [],
43308                     times = [],
43309                     heartRates = [],
43310                     line;
43311                 for (var i = 0; i < segments.length; i++) {
43312                     line = getPoints(segments[i], 'trkpt');
43313                     if (line) {
43314                         if (line.line) track.push(line.line);
43315                         if (line.times && line.times.length) times.push(line.times);
43316                         if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
43317                     }
43318                 }
43319                 if (track.length === 0) return;
43320                 var properties = getProperties(node);
43321                 extend(properties, getLineStyle(get1(node, 'extensions')));
43322                 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
43323                 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
43324                 return {
43325                     type: 'Feature',
43326                     properties: properties,
43327                     geometry: {
43328                         type: track.length === 1 ? 'LineString' : 'MultiLineString',
43329                         coordinates: track.length === 1 ? track[0] : track
43330                     }
43331                 };
43332             }
43333             function getRoute(node) {
43334                 var line = getPoints(node, 'rtept');
43335                 if (!line.line) return;
43336                 var prop = getProperties(node);
43337                 extend(prop, getLineStyle(get1(node, 'extensions')));
43338                 var routeObj = {
43339                     type: 'Feature',
43340                     properties: prop,
43341                     geometry: {
43342                         type: 'LineString',
43343                         coordinates: line.line
43344                     }
43345                 };
43346                 return routeObj;
43347             }
43348             function getPoint(node) {
43349                 var prop = getProperties(node);
43350                 extend(prop, getMulti(node, ['sym']));
43351                 return {
43352                     type: 'Feature',
43353                     properties: prop,
43354                     geometry: {
43355                         type: 'Point',
43356                         coordinates: coordPair(node).coordinates
43357                     }
43358                 };
43359             }
43360             function getLineStyle(extensions) {
43361                 var style = {};
43362                 if (extensions) {
43363                     var lineStyle = get1(extensions, 'line');
43364                     if (lineStyle) {
43365                         var color = nodeVal(get1(lineStyle, 'color')),
43366                             opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
43367                             width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43368                         if (color) style.stroke = color;
43369                         if (!isNaN(opacity)) style['stroke-opacity'] = opacity;
43370                         // GPX width is in mm, convert to px with 96 px per inch
43371                         if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
43372                     }
43373                 }
43374                 return style;
43375             }
43376             function getProperties(node) {
43377                 var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
43378                     links = get(node, 'link');
43379                 if (links.length) prop.links = [];
43380                 for (var i = 0, link; i < links.length; i++) {
43381                     link = { href: attr(links[i], 'href') };
43382                     extend(link, getMulti(links[i], ['text', 'type']));
43383                     prop.links.push(link);
43384                 }
43385                 return prop;
43386             }
43387             return gj;
43388         }
43389     };
43390     return t;
43391 })();
43392
43393 module.exports = toGeoJSON;
43394 });
43395
43396 function svgGpx(projection$$1, context, dispatch$$1) {
43397     var showLabels = true,
43398         detected = utilDetect(),
43399         layer;
43400
43401
43402     function init() {
43403         if (svgGpx.initialized) return;  // run once
43404
43405         svgGpx.geojson = {};
43406         svgGpx.enabled = true;
43407
43408         function over() {
43409             event.stopPropagation();
43410             event.preventDefault();
43411             event.dataTransfer.dropEffect = 'copy';
43412         }
43413
43414         select('body')
43415             .attr('dropzone', 'copy')
43416             .on('drop.localgpx', function() {
43417                 event.stopPropagation();
43418                 event.preventDefault();
43419                 if (!detected.filedrop) return;
43420                 drawGpx.files(event.dataTransfer.files);
43421             })
43422             .on('dragenter.localgpx', over)
43423             .on('dragexit.localgpx', over)
43424             .on('dragover.localgpx', over);
43425
43426         svgGpx.initialized = true;
43427     }
43428
43429
43430     function drawGpx(selection$$1) {
43431         var geojson = svgGpx.geojson,
43432             enabled = svgGpx.enabled;
43433
43434         layer = selection$$1.selectAll('.layer-gpx')
43435             .data(enabled ? [0] : []);
43436
43437         layer.exit()
43438             .remove();
43439
43440         layer = layer.enter()
43441             .append('g')
43442             .attr('class', 'layer-gpx')
43443             .merge(layer);
43444
43445
43446         var paths = layer
43447             .selectAll('path')
43448             .data([geojson]);
43449
43450         paths.exit()
43451             .remove();
43452
43453         paths = paths.enter()
43454             .append('path')
43455             .attr('class', 'gpx')
43456             .merge(paths);
43457
43458
43459         var path$$1 = index$4(projection$$1);
43460
43461         paths
43462             .attr('d', path$$1);
43463
43464
43465         var labels = layer.selectAll('text')
43466             .data(showLabels && geojson.features ? geojson.features : []);
43467
43468         labels.exit()
43469             .remove();
43470
43471         labels = labels.enter()
43472             .append('text')
43473             .attr('class', 'gpx')
43474             .merge(labels);
43475
43476         labels
43477             .text(function(d) {
43478                 return d.properties.desc || d.properties.name;
43479             })
43480             .attr('x', function(d) {
43481                 var centroid = path$$1.centroid(d);
43482                 return centroid[0] + 7;
43483             })
43484             .attr('y', function(d) {
43485                 var centroid = path$$1.centroid(d);
43486                 return centroid[1];
43487             });
43488
43489     }
43490
43491
43492     function toDom(x) {
43493         return (new DOMParser()).parseFromString(x, 'text/xml');
43494     }
43495
43496
43497     function getExtension(fileName) {
43498         if (lodash.isUndefined(fileName)) {
43499             return '';
43500         }
43501
43502         var lastDotIndex = fileName.lastIndexOf('.');
43503         if (lastDotIndex < 0) {
43504             return '';
43505         }
43506
43507         return fileName.substr(lastDotIndex);
43508     }
43509
43510
43511     function parseSaveAndZoom(extension, data) {
43512         switch (extension) {
43513             default:
43514                 drawGpx.geojson(togeojson.gpx(toDom(data))).fitZoom();
43515                 break;
43516             case '.kml':
43517                 drawGpx.geojson(togeojson.kml(toDom(data))).fitZoom();
43518                 break;
43519             case '.geojson':
43520             case '.json':
43521                 drawGpx.geojson(JSON.parse(data)).fitZoom();
43522                 break;
43523         }
43524     }
43525
43526
43527     drawGpx.showLabels = function(_) {
43528         if (!arguments.length) return showLabels;
43529         showLabels = _;
43530         return this;
43531     };
43532
43533
43534     drawGpx.enabled = function(_) {
43535         if (!arguments.length) return svgGpx.enabled;
43536         svgGpx.enabled = _;
43537         dispatch$$1.call('change');
43538         return this;
43539     };
43540
43541
43542     drawGpx.hasGpx = function() {
43543         var geojson = svgGpx.geojson;
43544         return (!(lodash.isEmpty(geojson) || lodash.isEmpty(geojson.features)));
43545     };
43546
43547
43548     drawGpx.geojson = function(gj) {
43549         if (!arguments.length) return svgGpx.geojson;
43550         if (lodash.isEmpty(gj) || lodash.isEmpty(gj.features)) return this;
43551         svgGpx.geojson = gj;
43552         dispatch$$1.call('change');
43553         return this;
43554     };
43555
43556
43557     drawGpx.url = function(url) {
43558         text(url, function(err, data) {
43559             if (!err) {
43560                 var extension = getExtension(url);
43561                 parseSaveAndZoom(extension, data);
43562             }
43563         });
43564         return this;
43565     };
43566
43567
43568     drawGpx.files = function(fileList) {
43569         if (!fileList.length) return this;
43570         var f = fileList[0],
43571             reader = new FileReader();
43572
43573         reader.onload = (function(file) {
43574             var extension = getExtension(file.name);
43575
43576             return function (e) {
43577                 parseSaveAndZoom(extension, e.target.result);
43578             };
43579         })(f);
43580
43581         reader.readAsText(f);
43582         return this;
43583     };
43584
43585
43586     drawGpx.fitZoom = function() {
43587         if (!this.hasGpx()) return this;
43588         var geojson = svgGpx.geojson;
43589
43590         var map = context.map(),
43591             viewport = map.trimmedExtent().polygon(),
43592             coords = lodash.reduce(geojson.features, function(coords, feature) {
43593                 var c = feature.geometry.coordinates;
43594
43595                 /* eslint-disable no-fallthrough */
43596                 switch (feature.geometry.type) {
43597                     case 'Point':
43598                         c = [c];
43599                     case 'MultiPoint':
43600                     case 'LineString':
43601                         break;
43602
43603                     case 'MultiPolygon':
43604                         c = lodash.flatten(c);
43605                     case 'Polygon':
43606                     case 'MultiLineString':
43607                         c = lodash.flatten(c);
43608                         break;
43609                 }
43610                 /* eslint-enable no-fallthrough */
43611
43612                 return lodash.union(coords, c);
43613             }, []);
43614
43615         if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
43616             var extent$$1 = geoExtent$$1(bounds({ type: 'LineString', coordinates: coords }));
43617             map.centerZoom(extent$$1.center(), map.trimmedExtentZoom(extent$$1));
43618         }
43619
43620         return this;
43621     };
43622
43623
43624     init();
43625     return drawGpx;
43626 }
43627
43628 function svgIcon(name, svgklass, useklass) {
43629     return function drawIcon(selection) {
43630         selection.selectAll('svg')
43631             .data([0])
43632             .enter()
43633             .append('svg')
43634             .attr('class', 'icon ' + (svgklass || ''))
43635             .append('use')
43636             .attr('xlink:href', name)
43637             .attr('class', useklass);
43638     };
43639 }
43640
43641 function svgLabels(projection$$1, context) {
43642     var path$$1 = index$4(projection$$1),
43643         detected = utilDetect(),
43644         baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge'),
43645         rdrawn = index$9(),
43646         rskipped = index$9(),
43647         textWidthCache = {},
43648         entitybboxes = {};
43649
43650     // Listed from highest to lowest priority
43651     var labelStack = [
43652         ['line', 'aeroway', '*', 12],
43653         ['line', 'highway', 'motorway', 12],
43654         ['line', 'highway', 'trunk', 12],
43655         ['line', 'highway', 'primary', 12],
43656         ['line', 'highway', 'secondary', 12],
43657         ['line', 'highway', 'tertiary', 12],
43658         ['line', 'highway', '*', 12],
43659         ['line', 'railway', '*', 12],
43660         ['line', 'waterway', '*', 12],
43661         ['area', 'aeroway', '*', 12],
43662         ['area', 'amenity', '*', 12],
43663         ['area', 'building', '*', 12],
43664         ['area', 'historic', '*', 12],
43665         ['area', 'leisure', '*', 12],
43666         ['area', 'man_made', '*', 12],
43667         ['area', 'natural', '*', 12],
43668         ['area', 'shop', '*', 12],
43669         ['area', 'tourism', '*', 12],
43670         ['area', 'camp_site', '*', 12],
43671         ['point', 'aeroway', '*', 10],
43672         ['point', 'amenity', '*', 10],
43673         ['point', 'building', '*', 10],
43674         ['point', 'historic', '*', 10],
43675         ['point', 'leisure', '*', 10],
43676         ['point', 'man_made', '*', 10],
43677         ['point', 'natural', '*', 10],
43678         ['point', 'shop', '*', 10],
43679         ['point', 'tourism', '*', 10],
43680         ['point', 'camp_site', '*', 10],
43681         ['line', 'name', '*', 12],
43682         ['area', 'name', '*', 12],
43683         ['point', 'name', '*', 10]
43684     ];
43685
43686
43687     function blacklisted(preset) {
43688         var noIcons = ['building', 'landuse', 'natural'];
43689         return lodash.some(noIcons, function(s) {
43690             return preset.id.indexOf(s) >= 0;
43691         });
43692     }
43693
43694
43695     function get(array, prop) {
43696         return function(d, i) { return array[i][prop]; };
43697     }
43698
43699
43700     function textWidth(text$$1, size, elem) {
43701         var c = textWidthCache[size];
43702         if (!c) c = textWidthCache[size] = {};
43703
43704         if (c[text$$1]) {
43705             return c[text$$1];
43706
43707         } else if (elem) {
43708             c[text$$1] = elem.getComputedTextLength();
43709             return c[text$$1];
43710
43711         } else {
43712             var str = encodeURIComponent(text$$1).match(/%[CDEFcdef]/g);
43713             if (str === null) {
43714                 return size / 3 * 2 * text$$1.length;
43715             } else {
43716                 return size / 3 * (2 * text$$1.length + str.length);
43717             }
43718         }
43719     }
43720
43721
43722     function drawLinePaths(selection$$1, entities, filter, classes, labels) {
43723         var paths = selection$$1.selectAll('path')
43724             .filter(filter)
43725             .data(entities, osmEntity$$1.key);
43726
43727         paths.exit()
43728             .remove();
43729
43730         paths.enter()
43731             .append('path')
43732             .style('stroke-width', get(labels, 'font-size'))
43733             .attr('id', function(d) { return 'labelpath-' + d.id; })
43734             .attr('class', classes)
43735             .merge(paths)
43736             .attr('d', get(labels, 'lineString'));
43737     }
43738
43739
43740     function drawLineLabels(selection$$1, entities, filter, classes, labels) {
43741         var texts = selection$$1.selectAll('text.' + classes)
43742             .filter(filter)
43743             .data(entities, osmEntity$$1.key);
43744
43745         texts.exit()
43746             .remove();
43747
43748         texts.enter()
43749             .append('text')
43750             .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
43751             .attr('dy', baselineHack ? '0.35em' : null)
43752             .append('textPath')
43753             .attr('class', 'textpath');
43754
43755         texts = selection$$1.selectAll('text.' + classes);
43756
43757         texts.selectAll('.textpath')
43758             .filter(filter)
43759             .data(entities, osmEntity$$1.key)
43760             .attr('startOffset', '50%')
43761             .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
43762             .text(utilDisplayNameForPath);
43763     }
43764
43765
43766     function drawPointLabels(selection$$1, entities, filter, classes, labels) {
43767         var texts = selection$$1.selectAll('text.' + classes)
43768             .filter(filter)
43769             .data(entities, osmEntity$$1.key);
43770
43771         texts.exit()
43772             .remove();
43773
43774         texts = texts.enter()
43775             .append('text')
43776             .attr('class', function(d, i) {
43777                 return classes + ' ' + labels[i].classes + ' ' + d.id;
43778             })
43779             .merge(texts);
43780
43781         texts
43782             .attr('x', get(labels, 'x'))
43783             .attr('y', get(labels, 'y'))
43784             .style('text-anchor', get(labels, 'textAnchor'))
43785             .text(utilDisplayName)
43786             .each(function(d, i) {
43787                 textWidth(utilDisplayName(d), labels[i].height, this);
43788             });
43789     }
43790
43791
43792     function drawAreaLabels(selection$$1, entities, filter, classes, labels) {
43793         entities = entities.filter(hasText);
43794         labels = labels.filter(hasText);
43795         drawPointLabels(selection$$1, entities, filter, classes, labels);
43796
43797         function hasText(d, i) {
43798             return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
43799         }
43800     }
43801
43802
43803     function drawAreaIcons(selection$$1, entities, filter, classes, labels) {
43804         var icons = selection$$1.selectAll('use.' + classes)
43805             .filter(filter)
43806             .data(entities, osmEntity$$1.key);
43807
43808         icons.exit()
43809             .remove();
43810
43811         icons = icons.enter()
43812             .append('use')
43813             .attr('class', 'icon ' + classes)
43814             .attr('width', '17px')
43815             .attr('height', '17px')
43816             .merge(icons);
43817
43818         icons
43819             .attr('transform', get(labels, 'transform'))
43820             .attr('xlink:href', function(d) {
43821                 var preset = context.presets().match(d, context.graph()),
43822                     picon = preset && preset.icon;
43823
43824                 if (!picon)
43825                     return '';
43826                 else {
43827                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
43828                     return '#' + picon + (isMaki ? '-15' : '');
43829                 }
43830             });
43831     }
43832
43833
43834     function drawCollisionBoxes(selection$$1, rtree, which) {
43835         var showDebug = context.getDebug('collision'),
43836             classes = 'debug ' + which + ' ' +
43837                 (which === 'debug-skipped' ? 'orange' : 'yellow');
43838
43839         var debug = selection$$1.selectAll('.layer-label-debug')
43840                 .data(showDebug ? [true] : []);
43841
43842         debug.exit()
43843             .remove();
43844
43845         debug = debug.enter()
43846             .append('g')
43847             .attr('class', 'layer-label-debug')
43848             .merge(debug);
43849
43850         if (showDebug) {
43851             var gj = rtree.all().map(function(d) {
43852                 return { type: 'Polygon', coordinates: [[
43853                     [d.minX, d.minY],
43854                     [d.maxX, d.minY],
43855                     [d.maxX, d.maxY],
43856                     [d.minX, d.maxY],
43857                     [d.minX, d.minY]
43858                 ]]};
43859             });
43860
43861             var debugboxes = debug.selectAll('.' + which)
43862                 .data(gj);
43863
43864             debugboxes.exit()
43865                 .remove();
43866
43867             debugboxes = debugboxes.enter()
43868                 .append('path')
43869                 .attr('class', classes)
43870                 .merge(debugboxes);
43871
43872             debugboxes
43873                 .attr('d', index$4());
43874         }
43875     }
43876
43877
43878     function drawLabels(selection$$1, graph, entities, filter, dimensions, fullRedraw) {
43879         var lowZoom = context.surface().classed('low-zoom');
43880
43881         var labelable = [], i, j, k, entity, geometry;
43882         for (i = 0; i < labelStack.length; i++) {
43883             labelable.push([]);
43884         }
43885
43886         if (fullRedraw) {
43887             rdrawn.clear();
43888             rskipped.clear();
43889             entitybboxes = {};
43890         } else {
43891             for (i = 0; i < entities.length; i++) {
43892                 entity = entities[i];
43893                 var toRemove = []
43894                     .concat(entitybboxes[entity.id] || [])
43895                     .concat(entitybboxes[entity.id + 'I'] || []);
43896
43897                 for (j = 0; j < toRemove.length; j++) {
43898                     rdrawn.remove(toRemove[j]);
43899                     rskipped.remove(toRemove[j]);
43900                 }
43901             }
43902         }
43903
43904         // Split entities into groups specified by labelStack
43905         for (i = 0; i < entities.length; i++) {
43906             entity = entities[i];
43907             geometry = entity.geometry(graph);
43908             if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
43909
43910             var preset = geometry === 'area' && context.presets().match(entity, graph),
43911                 icon = preset && !blacklisted(preset) && preset.icon;
43912
43913             if (!icon && !utilDisplayName(entity))
43914                 continue;
43915
43916             for (k = 0; k < labelStack.length; k++) {
43917                 var matchGeom = labelStack[k][0],
43918                     matchKey = labelStack[k][1],
43919                     matchVal = labelStack[k][2],
43920                     hasVal = entity.tags[matchKey];
43921
43922                 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
43923                     labelable[k].push(entity);
43924                     break;
43925                 }
43926             }
43927         }
43928
43929         var positions = {
43930             point: [],
43931             line: [],
43932             area: []
43933         };
43934
43935         var labelled = {
43936             point: [],
43937             line: [],
43938             area: []
43939         };
43940
43941         // Try and find a valid label for labellable entities
43942         for (k = 0; k < labelable.length; k++) {
43943             var fontSize = labelStack[k][3];
43944             for (i = 0; i < labelable[k].length; i++) {
43945                 entity = labelable[k][i];
43946                 geometry = entity.geometry(graph);
43947
43948                 var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName,
43949                     name = getName(entity),
43950                     width = name && textWidth(name, fontSize),
43951                     p;
43952
43953                 if (geometry === 'point') {
43954                     p = getPointLabel(entity, width, fontSize, geometry);
43955                 } else if (geometry === 'vertex' && !lowZoom) {
43956                     // don't label vertices at low zoom because they don't have icons
43957                     p = getPointLabel(entity, width, fontSize, geometry);
43958                 } else if (geometry === 'line') {
43959                     p = getLineLabel(entity, width, fontSize);
43960                 } else if (geometry === 'area') {
43961                     p = getAreaLabel(entity, width, fontSize);
43962                 }
43963
43964                 if (p) {
43965                     if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
43966                     p.classes = geometry + ' tag-' + labelStack[k][1];
43967                     positions[geometry].push(p);
43968                     labelled[geometry].push(entity);
43969                 }
43970             }
43971         }
43972
43973
43974         function getPointLabel(entity, width, height, geometry) {
43975             var y = (geometry === 'point' ? -12 : 0),
43976                 pointOffsets = {
43977                     ltr: [15, y, 'start'],
43978                     rtl: [-15, y, 'end']
43979                 };
43980
43981             var coord = projection$$1(entity.loc),
43982                 margin = 2,
43983                 offset = pointOffsets[textDirection],
43984                 p = {
43985                     height: height,
43986                     width: width,
43987                     x: coord[0] + offset[0],
43988                     y: coord[1] + offset[1],
43989                     textAnchor: offset[2]
43990                 },
43991                 bbox;
43992
43993             if (textDirection === 'rtl') {
43994                 bbox = {
43995                     minX: p.x - width - margin,
43996                     minY: p.y - (height / 2) - margin,
43997                     maxX: p.x + margin,
43998                     maxY: p.y + (height / 2) + margin
43999                 };
44000             } else {
44001                 bbox = {
44002                     minX: p.x - margin,
44003                     minY: p.y - (height / 2) - margin,
44004                     maxX: p.x + width + margin,
44005                     maxY: p.y + (height / 2) + margin
44006                 };
44007             }
44008
44009             if (tryInsert([bbox], entity.id, true)) {
44010                 return p;
44011             }
44012         }
44013
44014
44015         function getLineLabel(entity, width, height) {
44016             var viewport = geoExtent$$1(context.projection.clipExtent()).polygon(),
44017                 nodes = lodash.map(graph.childNodes(entity), 'loc').map(projection$$1),
44018                 length = geoPathLength(nodes);
44019
44020             if (length < width + 20) return;
44021
44022             // % along the line to attempt to place the label
44023             var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
44024                                25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
44025             var margin = 3;
44026
44027             for (var i = 0; i < lineOffsets.length; i++) {
44028                 var offset = lineOffsets[i],
44029                     middle = offset / 100 * length,
44030                     start = middle - width / 2;
44031
44032                 if (start < 0 || start + width > length) continue;
44033
44034                 // generate subpath and ignore paths that are invalid or don't cross viewport.
44035                 var sub = subpath(nodes, start, start + width);
44036                 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
44037                     continue;
44038                 }
44039
44040                 var isReverse = reverse$$1(sub);
44041                 if (isReverse) {
44042                     sub = sub.reverse();
44043                 }
44044
44045                 var bboxes = [],
44046                     boxsize = (height + 2) / 2;
44047
44048                 for (var j = 0; j < sub.length - 1; j++) {
44049                     var a = sub[j];
44050                     var b = sub[j + 1];
44051                     var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
44052
44053                     for (var box = 0; box < num; box++) {
44054                         var p = geoInterp(a, b, box / num);
44055                         var x0 = p[0] - boxsize - margin;
44056                         var y0 = p[1] - boxsize - margin;
44057                         var x1 = p[0] + boxsize + margin;
44058                         var y1 = p[1] + boxsize + margin;
44059
44060                         bboxes.push({
44061                             minX: Math.min(x0, x1),
44062                             minY: Math.min(y0, y1),
44063                             maxX: Math.max(x0, x1),
44064                             maxY: Math.max(y0, y1)
44065                         });
44066                     }
44067                 }
44068
44069                 if (tryInsert(bboxes, entity.id, false)) {
44070                     return {
44071                         'font-size': height + 2,
44072                         lineString: lineString(sub),
44073                         startOffset: offset + '%'
44074                     };
44075                 }
44076             }
44077
44078             function reverse$$1(p) {
44079                 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
44080                 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
44081             }
44082
44083             function lineString(nodes) {
44084                 return 'M' + nodes.join('L');
44085             }
44086
44087             function subpath(nodes, from, to) {
44088                 var sofar = 0,
44089                     start, end, i0, i1;
44090
44091                 for (var i = 0; i < nodes.length - 1; i++) {
44092                     var a = nodes[i],
44093                         b = nodes[i + 1];
44094                     var current = geoEuclideanDistance(a, b);
44095                     var portion;
44096                     if (!start && sofar + current >= from) {
44097                         portion = (from - sofar) / current;
44098                         start = [
44099                             a[0] + portion * (b[0] - a[0]),
44100                             a[1] + portion * (b[1] - a[1])
44101                         ];
44102                         i0 = i + 1;
44103                     }
44104                     if (!end && sofar + current >= to) {
44105                         portion = (to - sofar) / current;
44106                         end = [
44107                             a[0] + portion * (b[0] - a[0]),
44108                             a[1] + portion * (b[1] - a[1])
44109                         ];
44110                         i1 = i + 1;
44111                     }
44112                     sofar += current;
44113                 }
44114
44115                 var ret = nodes.slice(i0, i1);
44116                 ret.unshift(start);
44117                 ret.push(end);
44118                 return ret;
44119             }
44120         }
44121
44122
44123         function getAreaLabel(entity, width, height) {
44124             var centroid = path$$1.centroid(entity.asGeoJSON(graph, true)),
44125                 extent$$1 = entity.extent(graph),
44126                 entitywidth = projection$$1(extent$$1[1])[0] - projection$$1(extent$$1[0])[0];
44127
44128             if (isNaN(centroid[0]) || entitywidth < 20) return;
44129
44130             var iconSize = 20,
44131                 iconX = centroid[0] - (iconSize / 2),
44132                 iconY = centroid[1] - (iconSize / 2),
44133                 margin = 2,
44134                 textOffset = iconSize + margin,
44135                 p = { transform: 'translate(' + iconX + ',' + iconY + ')' };
44136
44137             var bbox = {
44138                 minX: iconX,
44139                 minY: iconY,
44140                 maxX: iconX + iconSize,
44141                 maxY: iconY + iconSize
44142             };
44143
44144             // try to add icon
44145             if (tryInsert([bbox], entity.id + 'I', true)) {
44146                 if (width && entitywidth >= width + 20) {
44147                     var labelX = centroid[0],
44148                         labelY = centroid[1] + textOffset;
44149
44150                     bbox = {
44151                         minX: labelX - (width / 2) - margin,
44152                         minY: labelY - (height / 2) - margin,
44153                         maxX: labelX + (width / 2) + margin,
44154                         maxY: labelY + (height / 2) + margin
44155                     };
44156
44157                     // try to add label
44158                     if (tryInsert([bbox], entity.id, true)) {
44159                         p.x = labelX;
44160                         p.y = labelY;
44161                         p.textAnchor = 'middle';
44162                         p.height = height;
44163                     }
44164                 }
44165
44166                 return p;
44167             }
44168         }
44169
44170
44171         function tryInsert(bboxes, id, saveSkipped) {
44172             var skipped = false,
44173                 bbox;
44174
44175             for (var i = 0; i < bboxes.length; i++) {
44176                 bbox = bboxes[i];
44177                 bbox.id = id;
44178
44179                 // Check that label is visible
44180                 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
44181                     skipped = true;
44182                     break;
44183                 }
44184                 if (rdrawn.collides(bbox)) {
44185                     skipped = true;
44186                     break;
44187                 }
44188             }
44189
44190             entitybboxes[id] = bboxes;
44191
44192             if (skipped) {
44193                 if (saveSkipped) {
44194                     rskipped.load(bboxes);
44195                 }
44196             } else {
44197                 rdrawn.load(bboxes);
44198             }
44199
44200             return !skipped;
44201         }
44202
44203
44204         var label = selection$$1.selectAll('.layer-label'),
44205             halo = selection$$1.selectAll('.layer-halo');
44206
44207         // points
44208         drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
44209         drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
44210
44211         // lines
44212         drawLinePaths(halo, labelled.line, filter, '', positions.line);
44213         drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
44214         drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
44215
44216         // areas
44217         drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
44218         drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
44219         drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
44220         drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);
44221
44222         // debug
44223         drawCollisionBoxes(label, rskipped, 'debug-skipped');
44224         drawCollisionBoxes(label, rdrawn, 'debug-drawn');
44225
44226         selection$$1.call(filterLabels);
44227     }
44228
44229
44230     function filterLabels(selection$$1) {
44231         var layers = selection$$1
44232             .selectAll('.layer-label, .layer-halo');
44233
44234         layers.selectAll('.proximate')
44235             .classed('proximate', false);
44236
44237         var mouse$$1 = context.mouse(),
44238             graph = context.graph(),
44239             selectedIDs = context.selectedIDs(),
44240             ids = [],
44241             pad, bbox;
44242
44243         // hide labels near the mouse
44244         if (mouse$$1) {
44245             pad = 20;
44246             bbox = { minX: mouse$$1[0] - pad, minY: mouse$$1[1] - pad, maxX: mouse$$1[0] + pad, maxY: mouse$$1[1] + pad };
44247             ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
44248         }
44249
44250         // hide labels along selected ways, or near selected vertices
44251         for (var i = 0; i < selectedIDs.length; i++) {
44252             var entity = graph.hasEntity(selectedIDs[i]);
44253             if (!entity) continue;
44254             var geometry = entity.geometry(graph);
44255
44256             if (geometry === 'line') {
44257                 ids.push(selectedIDs[i]);
44258             } else if (geometry === 'vertex') {
44259                 var point = context.projection(entity.loc);
44260                 pad = 10;
44261                 bbox = { minX: point[0] - pad, minY: point[1] - pad, maxX: point[0] + pad, maxY: point[1] + pad };
44262                 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
44263             }
44264         }
44265
44266         layers.selectAll(utilEntitySelector(ids))
44267             .classed('proximate', true);
44268     }
44269
44270
44271     var throttleFilterLabels = lodash.throttle(utilCallWhenIdle(filterLabels), 100);
44272
44273
44274     drawLabels.observe = function(selection$$1) {
44275         var listener = function() { throttleFilterLabels(selection$$1); };
44276         selection$$1.on('mousemove.hidelabels', listener);
44277         context.on('enter.hidelabels', listener);
44278     };
44279
44280
44281     drawLabels.off = function(selection$$1) {
44282         throttleFilterLabels.cancel();
44283         selection$$1.on('mousemove.hidelabels', null);
44284         context.on('enter.hidelabels', null);
44285     };
44286
44287
44288     return drawLabels;
44289 }
44290
44291 function refresh(selection, node) {
44292     var cr = node.getBoundingClientRect();
44293     var prop = [cr.width, cr.height];
44294     selection.property('__dimensions__', prop);
44295     return prop;
44296 }
44297
44298 function utilGetDimensions(selection, force) {
44299     if (!selection || selection.empty()) {
44300         return [0, 0];
44301     }
44302     var node = selection.node(),
44303         cached = selection.property('__dimensions__');
44304     return (!cached || force) ? refresh(selection, node) : cached;
44305 }
44306
44307
44308 function utilSetDimensions(selection, dimensions) {
44309     if (!selection || selection.empty()) {
44310         return selection;
44311     }
44312     var node = selection.node();
44313     if (dimensions === null) {
44314         refresh(selection, node);
44315         return selection;
44316     }
44317     return selection
44318         .property('__dimensions__', [dimensions[0], dimensions[1]])
44319         .attr('width', dimensions[0])
44320         .attr('height', dimensions[1]);
44321 }
44322
44323 function svgPointTransform(projection) {
44324     return function(entity) {
44325         // http://jsperf.com/short-array-join
44326         var pt = projection(entity.loc);
44327         return 'translate(' + pt[0] + ',' + pt[1] + ')';
44328     };
44329 }
44330
44331 function d3geoTile() {
44332   var size = [960, 500],
44333       scale = 256,
44334       scaleExtent = [0, 20],
44335       translate = [size[0] / 2, size[1] / 2],
44336       zoomDelta = 0;
44337
44338   function bound(_) {
44339       return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
44340   }
44341
44342   function tile() {
44343     var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
44344         z0 = bound(Math.round(z + zoomDelta)),
44345         k = Math.pow(2, z - z0 + 8),
44346         origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
44347         tiles = [],
44348         cols = sequence(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
44349         rows = sequence(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
44350
44351     rows.forEach(function(y) {
44352       cols.forEach(function(x) {
44353         tiles.push([x, y, z0]);
44354       });
44355     });
44356
44357     tiles.translate = origin;
44358     tiles.scale = k;
44359
44360     return tiles;
44361   }
44362
44363   tile.scaleExtent = function(_) {
44364     if (!arguments.length) return scaleExtent;
44365     scaleExtent = _;
44366     return tile;
44367   };
44368
44369   tile.size = function(_) {
44370     if (!arguments.length) return size;
44371     size = _;
44372     return tile;
44373   };
44374
44375   tile.scale = function(_) {
44376     if (!arguments.length) return scale;
44377     scale = _;
44378     return tile;
44379   };
44380
44381   tile.translate = function(_) {
44382     if (!arguments.length) return translate;
44383     translate = _;
44384     return tile;
44385   };
44386
44387   tile.zoomDelta = function(_) {
44388     if (!arguments.length) return zoomDelta;
44389     zoomDelta = +_;
44390     return tile;
44391   };
44392
44393   return tile;
44394 }
44395
44396 /* global Mapillary:false */
44397 var apibase = 'https://a.mapillary.com/v3/';
44398 var viewercss = 'mapillary-js/mapillary.min.css';
44399 var viewerjs = 'mapillary-js/mapillary.min.js';
44400 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
44401 var maxResults = 1000;
44402 var tileZoom = 14;
44403 var dispatch$2 = dispatch('loadedImages', 'loadedSigns');
44404 var mapillaryCache;
44405 var mapillaryClicks;
44406 var mapillaryImage;
44407 var mapillarySignDefs;
44408 var mapillarySignSprite;
44409 var mapillaryViewer;
44410
44411
44412 function abortRequest(i) {
44413     i.abort();
44414 }
44415
44416
44417 function nearNullIsland(x, y, z) {
44418     if (z >= 7) {
44419         var center = Math.pow(2, z - 1),
44420             width = Math.pow(2, z - 6),
44421             min$$1 = center - (width / 2),
44422             max$$1 = center + (width / 2) - 1;
44423         return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
44424     }
44425     return false;
44426 }
44427
44428
44429 function maxPageAtZoom(z) {
44430     if (z < 15)   return 2;
44431     if (z === 15) return 5;
44432     if (z === 16) return 10;
44433     if (z === 17) return 20;
44434     if (z === 18) return 40;
44435     if (z > 18)   return 80;
44436 }
44437
44438
44439 function getTiles(projection$$1) {
44440     var s = projection$$1.scale() * 2 * Math.PI,
44441         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
44442         ts = 256 * Math.pow(2, z - tileZoom),
44443         origin = [
44444             s / 2 - projection$$1.translate()[0],
44445             s / 2 - projection$$1.translate()[1]];
44446
44447     return d3geoTile()
44448         .scaleExtent([tileZoom, tileZoom])
44449         .scale(s)
44450         .size(projection$$1.clipExtent()[1])
44451         .translate(projection$$1.translate())()
44452         .map(function(tile) {
44453             var x = tile[0] * ts - origin[0],
44454                 y = tile[1] * ts - origin[1];
44455
44456             return {
44457                 id: tile.toString(),
44458                 xyz: tile,
44459                 extent: geoExtent$$1(
44460                     projection$$1.invert([x, y + ts]),
44461                     projection$$1.invert([x + ts, y])
44462                 )
44463             };
44464         });
44465 }
44466
44467
44468 function loadTiles(which, url, projection$$1) {
44469     var s = projection$$1.scale() * 2 * Math.PI,
44470         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
44471
44472     var tiles = getTiles(projection$$1).filter(function(t) {
44473             return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
44474         });
44475
44476     lodash.filter(which.inflight, function(v, k) {
44477         var wanted = lodash.find(tiles, function(tile) { return k === (tile.id + ',0'); });
44478         if (!wanted) delete which.inflight[k];
44479         return !wanted;
44480     }).map(abortRequest);
44481
44482     tiles.forEach(function(tile) {
44483         loadNextTilePage(which, currZoom, url, tile);
44484     });
44485 }
44486
44487
44488 function loadNextTilePage(which, currZoom, url, tile) {
44489     var cache = mapillaryCache[which],
44490         rect = tile.extent.rectangle(),
44491         maxPages = maxPageAtZoom(currZoom),
44492         nextPage = cache.nextPage[tile.id] || 0,
44493         nextURL = cache.nextURL[tile.id] || url +
44494             utilQsString({
44495                 per_page: maxResults,
44496                 page: nextPage,
44497                 client_id: clientId,
44498                 bbox: [rect[0], rect[1], rect[2], rect[3]].join(','),
44499             });
44500
44501     if (nextPage > maxPages) return;
44502
44503     var id = tile.id + ',' + String(nextPage);
44504     if (cache.loaded[id] || cache.inflight[id]) return;
44505     cache.inflight[id] = request(nextURL)
44506         .mimeType('application/json')
44507         .response(function(xhr) {
44508             var linkHeader = xhr.getResponseHeader('Link');
44509             if (linkHeader) {
44510                 var pagination = parsePagination(xhr.getResponseHeader('Link'));
44511                 if (pagination.next) {
44512                     cache.nextURL[tile.id] = pagination.next;
44513                 }
44514             }
44515             return JSON.parse(xhr.responseText);
44516         })
44517         .get(function(err, data) {
44518             cache.loaded[id] = true;
44519             delete cache.inflight[id];
44520             if (err || !data.features || !data.features.length) return;
44521
44522             var features = data.features.map(function(feature) {
44523                 var loc = feature.geometry.coordinates,
44524                     d;
44525
44526                 if (which === 'images') {
44527                     d = {
44528                         loc: loc,
44529                         key: feature.properties.key,
44530                         ca: feature.properties.ca,
44531                         captured_at: feature.properties.captured_at,
44532                         pano: feature.properties.pano
44533                     };
44534                 } else if (which === 'objects') {
44535                     d = {
44536                         loc: loc,
44537                         key: feature.properties.key,
44538                         value: feature.properties.value,
44539                         package: feature.properties.package,
44540                         detections: feature.properties.detections
44541                     };
44542
44543                     // cache image_key -> detection_key
44544                     feature.properties.detections.forEach(function(detection) {
44545                         var ik = detection.image_key;
44546                         var dk = detection.detection_key;
44547                         if (!mapillaryCache.detections[ik]) {
44548                             mapillaryCache.detections[ik] = {};
44549                         }
44550                         if (!mapillaryCache.detections[ik][dk]) {
44551                             mapillaryCache.detections[ik][dk] = {};
44552                         }
44553                     });
44554                 }
44555
44556                 return {
44557                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
44558                 };
44559             });
44560
44561             cache.rtree.load(features);
44562
44563             if (which === 'images') {
44564                 dispatch$2.call('loadedImages');
44565             } else if (which === 'objects') {
44566                 dispatch$2.call('loadedSigns');
44567             }
44568
44569             if (data.features.length === maxResults) {  // more pages to load
44570                 cache.nextPage[tile.id] = nextPage + 1;
44571                 loadNextTilePage(which, currZoom, url, tile);
44572             } else {
44573                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
44574             }
44575         });
44576 }
44577
44578 // extract links to pages of API results
44579 function parsePagination(links) {
44580     return links.split(',').map(function(rel) {
44581         var elements = rel.split(';');
44582         if (elements.length === 2) {
44583             return [
44584                 /<(.+)>/.exec(elements[0])[1],
44585                 /rel="(.+)"/.exec(elements[1])[1]
44586                 ];
44587         } else {
44588             return ['',''];
44589         }
44590     }).reduce(function(pagination, val) {
44591         pagination[val[1]] = val[0];
44592         return pagination;
44593     }, {});
44594 }
44595
44596
44597 // partition viewport into `psize` x `psize` regions
44598 function partitionViewport(psize, projection$$1) {
44599     var dimensions = projection$$1.clipExtent()[1];
44600     psize = psize || 16;
44601     var cols = sequence(0, dimensions[0], psize),
44602         rows = sequence(0, dimensions[1], psize),
44603         partitions = [];
44604
44605     rows.forEach(function(y) {
44606         cols.forEach(function(x) {
44607             var min$$1 = [x, y + psize],
44608                 max$$1 = [x + psize, y];
44609             partitions.push(
44610                 geoExtent$$1(projection$$1.invert(min$$1), projection$$1.invert(max$$1)));
44611         });
44612     });
44613
44614     return partitions;
44615 }
44616
44617
44618 // no more than `limit` results per partition.
44619 function searchLimited(psize, limit, projection$$1, rtree) {
44620     limit = limit || 3;
44621
44622     var partitions = partitionViewport(psize, projection$$1);
44623     return lodash.flatten(lodash.compact(lodash.map(partitions, function(extent$$1) {
44624         return rtree.search(extent$$1.bbox())
44625             .slice(0, limit)
44626             .map(function(d) { return d.data; });
44627     })));
44628 }
44629
44630
44631
44632 var serviceMapillary = {
44633
44634     init: function() {
44635         if (!mapillaryCache) {
44636             this.reset();
44637         }
44638
44639         this.event = utilRebind(this, dispatch$2, 'on');
44640     },
44641
44642     reset: function() {
44643         var cache = mapillaryCache;
44644
44645         if (cache) {
44646             if (cache.images && cache.images.inflight) {
44647                 lodash.forEach(cache.images.inflight, abortRequest);
44648             }
44649             if (cache.objects && cache.objects.inflight) {
44650                 lodash.forEach(cache.objects.inflight, abortRequest);
44651             }
44652         }
44653
44654         mapillaryCache = {
44655             images: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: index$9() },
44656             objects:  { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: index$9() },
44657             detections: {}
44658         };
44659
44660         mapillaryImage = null;
44661         mapillaryClicks = [];
44662     },
44663
44664
44665     images: function(projection$$1) {
44666         var psize = 16, limit = 3;
44667         return searchLimited(psize, limit, projection$$1, mapillaryCache.images.rtree);
44668     },
44669
44670
44671     signs: function(projection$$1) {
44672         var psize = 32, limit = 3;
44673         return searchLimited(psize, limit, projection$$1, mapillaryCache.objects.rtree);
44674     },
44675
44676
44677     signsSupported: function() {
44678         var detected = utilDetect();
44679         if (detected.ie) return false;
44680         if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
44681         return true;
44682     },
44683
44684
44685     signHTML: function(d) {
44686         if (!mapillarySignDefs || !mapillarySignSprite) return;
44687         var position = mapillarySignDefs[d.value];
44688         if (!position) return '<div></div>';
44689         var iconStyle = [
44690             'background-image:url(' + mapillarySignSprite + ')',
44691             'background-repeat:no-repeat',
44692             'height:' + position.height + 'px',
44693             'width:' + position.width + 'px',
44694             'background-position-x:-' + position.x + 'px',
44695             'background-position-y:-' + position.y + 'px',
44696         ];
44697
44698         return '<div style="' + iconStyle.join(';') +'"></div>';
44699     },
44700
44701
44702     loadImages: function(projection$$1) {
44703         var url = apibase + 'images?';
44704         loadTiles('images', url, projection$$1);
44705     },
44706
44707
44708     loadSigns: function(context, projection$$1) {
44709         var url = apibase + 'objects?';
44710         loadTiles('objects', url, projection$$1);
44711
44712         // load traffic sign defs
44713         if (!mapillarySignDefs) {
44714             mapillarySignSprite = context.asset('img/traffic-signs/traffic-signs.png');
44715             mapillarySignDefs = {};
44716             json(context.asset('img/traffic-signs/traffic-signs.json'), function(err, data) {
44717                 if (err) return;
44718                 mapillarySignDefs = data;
44719             });
44720         }
44721     },
44722
44723
44724     loadViewer: function(context) {
44725         var that = this;
44726         var wrap = select('#content').selectAll('.mapillary-wrap')
44727             .data([0]);
44728
44729         var enter = wrap.enter()
44730             .append('div')
44731             .attr('class', 'mapillary-wrap')
44732             .classed('al', true)       // 'al'=left,  'ar'=right
44733             .classed('hidden', true);
44734
44735         enter
44736             .append('button')
44737             .attr('class', 'thumb-hide')
44738             .on('click', function () { that.hideViewer(); })
44739             .append('div')
44740             .call(svgIcon('#icon-close'));
44741
44742         enter
44743             .append('div')
44744             .attr('id', 'mly')
44745             .attr('class', 'mly-wrapper')
44746             .classed('active', false);
44747
44748         // load mapillary-viewercss
44749         select('head').selectAll('#mapillary-viewercss')
44750             .data([0])
44751             .enter()
44752             .append('link')
44753             .attr('id', 'mapillary-viewercss')
44754             .attr('rel', 'stylesheet')
44755             .attr('href', context.asset(viewercss));
44756
44757         // load mapillary-viewerjs
44758         select('head').selectAll('#mapillary-viewerjs')
44759             .data([0])
44760             .enter()
44761             .append('script')
44762             .attr('id', 'mapillary-viewerjs')
44763             .attr('src', context.asset(viewerjs));
44764     },
44765
44766
44767     showViewer: function() {
44768         select('#content')
44769             .selectAll('.mapillary-wrap')
44770             .classed('hidden', false)
44771             .selectAll('.mly-wrapper')
44772             .classed('active', true);
44773
44774         return this;
44775     },
44776
44777
44778     hideViewer: function() {
44779         select('#content')
44780             .selectAll('.mapillary-wrap')
44781             .classed('hidden', true)
44782             .selectAll('.mly-wrapper')
44783             .classed('active', false);
44784
44785         selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
44786             .classed('selected', false);
44787
44788         mapillaryImage = null;
44789         return this;
44790     },
44791
44792
44793     parsePagination: parsePagination,
44794
44795
44796     updateViewer: function(imageKey, context) {
44797         if (!imageKey) return;
44798
44799         if (!mapillaryViewer) {
44800             this.initViewer(imageKey, context);
44801         } else {
44802             mapillaryViewer.moveToKey(imageKey);
44803         }
44804
44805         return this;
44806     },
44807
44808
44809     initViewer: function(imageKey, context) {
44810         var that = this;
44811         if (Mapillary && imageKey) {
44812             var opts = {
44813                 baseImageSize: 320,
44814                 component: {
44815                     cover: false,
44816                     keyboard: false,
44817                     tag: true
44818                 }
44819             };
44820
44821             mapillaryViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
44822             mapillaryViewer.on('nodechanged', nodeChanged);
44823         }
44824
44825         // nodeChanged: called after the viewer has changed images and is ready.
44826         //
44827         // There is some logic here to batch up clicks into a mapillaryClicks array
44828         // because the user might click on a lot of markers quickly and nodechanged
44829         // may be called out of order asychronously.
44830         //
44831         // Clicks are added to the array in `selectedImage` and removed here.
44832         //
44833         function nodeChanged(node) {
44834             mapillaryViewer.getComponent('tag').removeAll();  // remove previous detections
44835
44836             var clicks = mapillaryClicks;
44837             var index = clicks.indexOf(node.key);
44838             if (index > -1) {    // `nodechanged` initiated from clicking on a marker..
44839                 clicks.splice(index, 1);
44840                 // If `node.key` matches the current mapillaryImage, call `selectedImage()`
44841                 // one more time to update the detections and attribution..
44842                 if (node.key === mapillaryImage) {
44843                     that.selectedImage(node.key, false);
44844                 }
44845             } else {             // `nodechanged` initiated from the Mapillary viewer controls..
44846                 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
44847                 context.map().centerEase(loc);
44848                 that.selectedImage(node.key, false);
44849             }
44850         }
44851     },
44852
44853
44854     selectedImage: function(imageKey, fromClick) {
44855         if (!arguments.length) return mapillaryImage;
44856         mapillaryImage = imageKey;
44857
44858         if (fromClick) {
44859             mapillaryClicks.push(imageKey);
44860         }
44861
44862         selectAll('.layer-mapillary-images .viewfield-group')
44863             .classed('selected', function(d) {
44864                 return d.key === imageKey;
44865             });
44866
44867         selectAll('.layer-mapillary-signs .icon-sign')
44868             .classed('selected', function(d) {
44869                 return lodash.some(d.detections, function(detection) {
44870                     return detection.image_key === imageKey;
44871                 });
44872             });
44873
44874         if (!imageKey)  return this;
44875
44876
44877         function localeTimestamp(s) {
44878             if (!s) return null;
44879             var d = new Date(s);
44880             if (isNaN(d.getTime())) return null;
44881             return d.toLocaleString(undefined, { timeZone: 'UTC' });
44882         }
44883
44884         var selected = selectAll('.layer-mapillary-images .viewfield-group.selected');
44885         if (selected.empty()) return this;
44886
44887         var datum = selected.datum();
44888         var timestamp = localeTimestamp(datum.captured_at);
44889         var attribution = select('.mapillary-js-dom .Attribution');
44890         var capturedAt = attribution.selectAll('.captured-at');
44891         if (capturedAt.empty()) {
44892             attribution
44893                 .append('span')
44894                 .text('|');
44895             capturedAt = attribution
44896                 .append('span')
44897                 .attr('class', 'captured-at');
44898         }
44899         capturedAt
44900             .text(timestamp);
44901
44902         this.updateDetections();
44903
44904         return this;
44905     },
44906
44907
44908     updateDetections: function() {
44909         if (!mapillaryViewer) return;
44910
44911         var detections = mapillaryCache.detections[mapillaryImage];
44912         lodash.each(detections, function(data, k) {
44913             if (lodash.isEmpty(data)) {
44914                 loadDetection(k);
44915             } else {
44916                 var tag = makeTag(data);
44917                 if (tag) {
44918                     var tagComponent = mapillaryViewer.getComponent('tag');
44919                     tagComponent.add([tag]);
44920                 }
44921             }
44922         });
44923
44924
44925         function loadDetection(detectionKey) {
44926             var url = apibase + 'detections/'+
44927                 detectionKey + '?' + utilQsString({
44928                     client_id: clientId,
44929                 });
44930
44931             request(url)
44932                 .mimeType('application/json')
44933                 .response(function(xhr) {
44934                     return JSON.parse(xhr.responseText);
44935                 })
44936                 .get(function(err, data) {
44937                     if (!data || !data.properties) return;
44938
44939                     var ik = data.properties.image_key;
44940                     mapillaryCache.detections[ik][detectionKey] = data;
44941
44942                     if (mapillaryImage === ik) {
44943                         var tag = makeTag(data);
44944                         if (tag) {
44945                             var tagComponent = mapillaryViewer.getComponent('tag');
44946                             tagComponent.add([tag]);
44947                         }
44948                     }
44949                 });
44950         }
44951
44952
44953         function makeTag(data) {
44954             var valueParts = data.properties.value.split('--');
44955             if (valueParts.length !== 3) return;
44956
44957             var text$$1 = valueParts[1].replace(/-/g, ' ');
44958             var tag;
44959
44960             // Currently only two shapes <Polygon|Point>
44961             if (data.properties.shape.type === 'Polygon') {
44962                 var polygonGeometry = new Mapillary
44963                     .TagComponent
44964                     .PolygonGeometry(data.properties.shape.coordinates[0]);
44965
44966                 tag = new Mapillary.TagComponent.OutlineTag(
44967                     data.properties.key,
44968                     polygonGeometry,
44969                     {
44970                         text: text$$1,
44971                         textColor: 0xffff00,
44972                         lineColor: 0xffff00,
44973                         lineWidth: 2,
44974                         fillColor: 0xffff00,
44975                         fillOpacity: 0.3,
44976                     }
44977                 );
44978
44979             } else if (data.properties.shape.type === 'Point') {
44980                 var pointGeometry = new Mapillary
44981                     .TagComponent
44982                     .PointGeometry(data.properties.shape.coordinates[0]);
44983
44984                 tag = new Mapillary.TagComponent.SpotTag(
44985                     data.properties.key,
44986                     pointGeometry,
44987                     {
44988                         text: text$$1,
44989                         color: 0xffff00,
44990                         textColor: 0xffff00
44991                     }
44992                 );
44993             }
44994
44995             return tag;
44996         }
44997     },
44998
44999
45000     cache: function(_) {
45001         if (!arguments.length) return mapillaryCache;
45002         mapillaryCache = _;
45003         return this;
45004     },
45005
45006
45007     signDefs: function(_) {
45008         if (!arguments.length) return mapillarySignDefs;
45009         mapillarySignDefs = _;
45010         return this;
45011     }
45012
45013 };
45014
45015 var apibase$1 = 'https://nominatim.openstreetmap.org/';
45016 var inflight = {};
45017 var nominatimCache;
45018
45019
45020 var serviceNominatim = {
45021
45022     init: function() {
45023         inflight = {};
45024         nominatimCache = index$9();
45025     },
45026
45027     reset: function() {
45028         lodash.forEach(inflight, function(req) { req.abort(); });
45029         inflight = {};
45030         nominatimCache = index$9();
45031     },
45032
45033
45034     countryCode: function (location, callback) {
45035         this.reverse(location, function(err, result) {
45036             if (err) {
45037                 return callback(err);
45038             } else if (result.address) {
45039                 return callback(null, result.address.country_code);
45040             } else {
45041                 return callback('Unable to geocode', null);
45042             }
45043         });
45044     },
45045
45046
45047     reverse: function (location, callback) {
45048         var cached = nominatimCache.search(
45049             { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
45050         );
45051
45052         if (cached.length > 0) {
45053             return callback(null, cached[0].data);
45054         }
45055
45056         var params = { zoom: 13, format: 'json', addressdetails: 1, lat: location[1], lon: location[0] };
45057         var url = apibase$1 + 'reverse?' + utilQsString(params);
45058         if (inflight[url]) return;
45059
45060         inflight[url] = json(url, function(err, result) {
45061             delete inflight[url];
45062
45063             if (err) {
45064                 return callback(err);
45065             } else if (result && result.error) {
45066                 return callback(result.error);
45067             }
45068
45069             var extent$$1 = geoExtent$$1(location).padByMeters(200);
45070             nominatimCache.insert(lodash.assign(extent$$1.bbox(), {data: result}));
45071
45072             callback(null, result);
45073         });
45074     },
45075
45076
45077     search: function (val, callback) {
45078         var searchVal = encodeURIComponent(val);
45079         var url = apibase$1 + 'search/' + searchVal + '?limit=10&format=json';
45080         if (inflight[url]) return;
45081
45082         inflight[url] = json(url, function(err, result) {
45083             delete inflight[url];
45084             callback(err, result);
45085         });
45086     }
45087
45088 };
45089
45090 var hashes = createCommonjsModule(function (module, exports) {
45091 /**
45092  * jshashes - https://github.com/h2non/jshashes
45093  * Released under the "New BSD" license
45094  *
45095  * Algorithms specification:
45096  *
45097  * MD5 - http://www.ietf.org/rfc/rfc1321.txt
45098  * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
45099  * SHA1   - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
45100  * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
45101  * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
45102  * HMAC - http://www.ietf.org/rfc/rfc2104.txt
45103  */
45104 (function() {
45105   var Hashes;
45106
45107   function utf8Encode(str) {
45108     var x, y, output = '',
45109       i = -1,
45110       l;
45111
45112     if (str && str.length) {
45113       l = str.length;
45114       while ((i += 1) < l) {
45115         /* Decode utf-16 surrogate pairs */
45116         x = str.charCodeAt(i);
45117         y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
45118         if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
45119           x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
45120           i += 1;
45121         }
45122         /* Encode output as utf-8 */
45123         if (x <= 0x7F) {
45124           output += String.fromCharCode(x);
45125         } else if (x <= 0x7FF) {
45126           output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
45127             0x80 | (x & 0x3F));
45128         } else if (x <= 0xFFFF) {
45129           output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
45130             0x80 | ((x >>> 6) & 0x3F),
45131             0x80 | (x & 0x3F));
45132         } else if (x <= 0x1FFFFF) {
45133           output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
45134             0x80 | ((x >>> 12) & 0x3F),
45135             0x80 | ((x >>> 6) & 0x3F),
45136             0x80 | (x & 0x3F));
45137         }
45138       }
45139     }
45140     return output;
45141   }
45142
45143   function utf8Decode(str) {
45144     var i, ac, c1, c2, c3, arr = [],
45145       l;
45146     i = ac = c1 = c2 = c3 = 0;
45147
45148     if (str && str.length) {
45149       l = str.length;
45150       str += '';
45151
45152       while (i < l) {
45153         c1 = str.charCodeAt(i);
45154         ac += 1;
45155         if (c1 < 128) {
45156           arr[ac] = String.fromCharCode(c1);
45157           i += 1;
45158         } else if (c1 > 191 && c1 < 224) {
45159           c2 = str.charCodeAt(i + 1);
45160           arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
45161           i += 2;
45162         } else {
45163           c2 = str.charCodeAt(i + 1);
45164           c3 = str.charCodeAt(i + 2);
45165           arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
45166           i += 3;
45167         }
45168       }
45169     }
45170     return arr.join('');
45171   }
45172
45173   /**
45174    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
45175    * to work around bugs in some JS interpreters.
45176    */
45177
45178   function safe_add(x, y) {
45179     var lsw = (x & 0xFFFF) + (y & 0xFFFF),
45180       msw = (x >> 16) + (y >> 16) + (lsw >> 16);
45181     return (msw << 16) | (lsw & 0xFFFF);
45182   }
45183
45184   /**
45185    * Bitwise rotate a 32-bit number to the left.
45186    */
45187
45188   function bit_rol(num, cnt) {
45189     return (num << cnt) | (num >>> (32 - cnt));
45190   }
45191
45192   /**
45193    * Convert a raw string to a hex string
45194    */
45195
45196   function rstr2hex(input, hexcase) {
45197     var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
45198       output = '',
45199       x, i = 0,
45200       l = input.length;
45201     for (; i < l; i += 1) {
45202       x = input.charCodeAt(i);
45203       output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
45204     }
45205     return output;
45206   }
45207
45208   /**
45209    * Encode a string as utf-16
45210    */
45211
45212   function binb2rstr(input) {
45213     var i, l = input.length * 32,
45214       output = '';
45215     for (i = 0; i < l; i += 8) {
45216       output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
45217     }
45218     return output;
45219   }
45220
45221   /**
45222    * Convert an array of little-endian words to a string
45223    */
45224
45225   function binl2rstr(input) {
45226     var i, l = input.length * 32,
45227       output = '';
45228     for (i = 0; i < l; i += 8) {
45229       output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
45230     }
45231     return output;
45232   }
45233
45234   /**
45235    * Convert a raw string to an array of little-endian words
45236    * Characters >255 have their high-byte silently ignored.
45237    */
45238
45239   function rstr2binl(input) {
45240     var i, l = input.length * 8,
45241       output = Array(input.length >> 2),
45242       lo = output.length;
45243     for (i = 0; i < lo; i += 1) {
45244       output[i] = 0;
45245     }
45246     for (i = 0; i < l; i += 8) {
45247       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
45248     }
45249     return output;
45250   }
45251
45252   /**
45253    * Convert a raw string to an array of big-endian words
45254    * Characters >255 have their high-byte silently ignored.
45255    */
45256
45257   function rstr2binb(input) {
45258     var i, l = input.length * 8,
45259       output = Array(input.length >> 2),
45260       lo = output.length;
45261     for (i = 0; i < lo; i += 1) {
45262       output[i] = 0;
45263     }
45264     for (i = 0; i < l; i += 8) {
45265       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
45266     }
45267     return output;
45268   }
45269
45270   /**
45271    * Convert a raw string to an arbitrary string encoding
45272    */
45273
45274   function rstr2any(input, encoding) {
45275     var divisor = encoding.length,
45276       remainders = Array(),
45277       i, q, x, ld, quotient, dividend, output, full_length;
45278
45279     /* Convert to an array of 16-bit big-endian values, forming the dividend */
45280     dividend = Array(Math.ceil(input.length / 2));
45281     ld = dividend.length;
45282     for (i = 0; i < ld; i += 1) {
45283       dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
45284     }
45285
45286     /**
45287      * Repeatedly perform a long division. The binary array forms the dividend,
45288      * the length of the encoding is the divisor. Once computed, the quotient
45289      * forms the dividend for the next step. We stop when the dividend is zerHashes.
45290      * All remainders are stored for later use.
45291      */
45292     while (dividend.length > 0) {
45293       quotient = Array();
45294       x = 0;
45295       for (i = 0; i < dividend.length; i += 1) {
45296         x = (x << 16) + dividend[i];
45297         q = Math.floor(x / divisor);
45298         x -= q * divisor;
45299         if (quotient.length > 0 || q > 0) {
45300           quotient[quotient.length] = q;
45301         }
45302       }
45303       remainders[remainders.length] = x;
45304       dividend = quotient;
45305     }
45306
45307     /* Convert the remainders to the output string */
45308     output = '';
45309     for (i = remainders.length - 1; i >= 0; i--) {
45310       output += encoding.charAt(remainders[i]);
45311     }
45312
45313     /* Append leading zero equivalents */
45314     full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
45315     for (i = output.length; i < full_length; i += 1) {
45316       output = encoding[0] + output;
45317     }
45318     return output;
45319   }
45320
45321   /**
45322    * Convert a raw string to a base-64 string
45323    */
45324
45325   function rstr2b64(input, b64pad) {
45326     var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
45327       output = '',
45328       len = input.length,
45329       i, j, triplet;
45330     b64pad = b64pad || '=';
45331     for (i = 0; i < len; i += 3) {
45332       triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
45333       for (j = 0; j < 4; j += 1) {
45334         if (i * 8 + j * 6 > input.length * 8) {
45335           output += b64pad;
45336         } else {
45337           output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
45338         }
45339       }
45340     }
45341     return output;
45342   }
45343
45344   Hashes = {
45345     /**
45346      * @property {String} version
45347      * @readonly
45348      */
45349     VERSION: '1.0.6',
45350     /**
45351      * @member Hashes
45352      * @class Base64
45353      * @constructor
45354      */
45355     Base64: function() {
45356       // private properties
45357       var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
45358         pad = '=', // default pad according with the RFC standard
45359         url = false, // URL encoding support @todo
45360         utf8 = true; // by default enable UTF-8 support encoding
45361
45362       // public method for encoding
45363       this.encode = function(input) {
45364         var i, j, triplet,
45365           output = '',
45366           len = input.length;
45367
45368         pad = pad || '=';
45369         input = (utf8) ? utf8Encode(input) : input;
45370
45371         for (i = 0; i < len; i += 3) {
45372           triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
45373           for (j = 0; j < 4; j += 1) {
45374             if (i * 8 + j * 6 > len * 8) {
45375               output += pad;
45376             } else {
45377               output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
45378             }
45379           }
45380         }
45381         return output;
45382       };
45383
45384       // public method for decoding
45385       this.decode = function(input) {
45386         // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
45387         var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
45388           dec = '',
45389           arr = [];
45390         if (!input) {
45391           return input;
45392         }
45393
45394         i = ac = 0;
45395         input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
45396         //input += '';
45397
45398         do { // unpack four hexets into three octets using index points in b64
45399           h1 = tab.indexOf(input.charAt(i += 1));
45400           h2 = tab.indexOf(input.charAt(i += 1));
45401           h3 = tab.indexOf(input.charAt(i += 1));
45402           h4 = tab.indexOf(input.charAt(i += 1));
45403
45404           bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
45405
45406           o1 = bits >> 16 & 0xff;
45407           o2 = bits >> 8 & 0xff;
45408           o3 = bits & 0xff;
45409           ac += 1;
45410
45411           if (h3 === 64) {
45412             arr[ac] = String.fromCharCode(o1);
45413           } else if (h4 === 64) {
45414             arr[ac] = String.fromCharCode(o1, o2);
45415           } else {
45416             arr[ac] = String.fromCharCode(o1, o2, o3);
45417           }
45418         } while (i < input.length);
45419
45420         dec = arr.join('');
45421         dec = (utf8) ? utf8Decode(dec) : dec;
45422
45423         return dec;
45424       };
45425
45426       // set custom pad string
45427       this.setPad = function(str) {
45428         pad = str || pad;
45429         return this;
45430       };
45431       // set custom tab string characters
45432       this.setTab = function(str) {
45433         tab = str || tab;
45434         return this;
45435       };
45436       this.setUTF8 = function(bool) {
45437         if (typeof bool === 'boolean') {
45438           utf8 = bool;
45439         }
45440         return this;
45441       };
45442     },
45443
45444     /**
45445      * CRC-32 calculation
45446      * @member Hashes
45447      * @method CRC32
45448      * @static
45449      * @param {String} str Input String
45450      * @return {String}
45451      */
45452     CRC32: function(str) {
45453       var crc = 0,
45454         x = 0,
45455         y = 0,
45456         table, i, iTop;
45457       str = utf8Encode(str);
45458
45459       table = [
45460         '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
45461         '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
45462         '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
45463         '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
45464         'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
45465         '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
45466         'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
45467         '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
45468         'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
45469         '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
45470         'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
45471         '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
45472         'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
45473         '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
45474         '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
45475         '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
45476         '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
45477         'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
45478         '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
45479         'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
45480         '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
45481         'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
45482         '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
45483         'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
45484         '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
45485         'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
45486       ].join('');
45487
45488       crc = crc ^ (-1);
45489       for (i = 0, iTop = str.length; i < iTop; i += 1) {
45490         y = (crc ^ str.charCodeAt(i)) & 0xFF;
45491         x = '0x' + table.substr(y * 9, 8);
45492         crc = (crc >>> 8) ^ x;
45493       }
45494       // always return a positive number (that's what >>> 0 does)
45495       return (crc ^ (-1)) >>> 0;
45496     },
45497     /**
45498      * @member Hashes
45499      * @class MD5
45500      * @constructor
45501      * @param {Object} [config]
45502      *
45503      * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
45504      * Digest Algorithm, as defined in RFC 1321.
45505      * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
45506      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45507      * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
45508      */
45509     MD5: function(options) {
45510       /**
45511        * Private config properties. You may need to tweak these to be compatible with
45512        * the server-side, but the defaults work in most cases.
45513        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
45514        */
45515       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
45516         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
45517         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
45518
45519       // privileged (public) methods
45520       this.hex = function(s) {
45521         return rstr2hex(rstr(s, utf8), hexcase);
45522       };
45523       this.b64 = function(s) {
45524         return rstr2b64(rstr(s), b64pad);
45525       };
45526       this.any = function(s, e) {
45527         return rstr2any(rstr(s, utf8), e);
45528       };
45529       this.raw = function(s) {
45530         return rstr(s, utf8);
45531       };
45532       this.hex_hmac = function(k, d) {
45533         return rstr2hex(rstr_hmac(k, d), hexcase);
45534       };
45535       this.b64_hmac = function(k, d) {
45536         return rstr2b64(rstr_hmac(k, d), b64pad);
45537       };
45538       this.any_hmac = function(k, d, e) {
45539         return rstr2any(rstr_hmac(k, d), e);
45540       };
45541       /**
45542        * Perform a simple self-test to see if the VM is working
45543        * @return {String} Hexadecimal hash sample
45544        */
45545       this.vm_test = function() {
45546         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45547       };
45548       /**
45549        * Enable/disable uppercase hexadecimal returned string
45550        * @param {Boolean}
45551        * @return {Object} this
45552        */
45553       this.setUpperCase = function(a) {
45554         if (typeof a === 'boolean') {
45555           hexcase = a;
45556         }
45557         return this;
45558       };
45559       /**
45560        * Defines a base64 pad string
45561        * @param {String} Pad
45562        * @return {Object} this
45563        */
45564       this.setPad = function(a) {
45565         b64pad = a || b64pad;
45566         return this;
45567       };
45568       /**
45569        * Defines a base64 pad string
45570        * @param {Boolean}
45571        * @return {Object} [this]
45572        */
45573       this.setUTF8 = function(a) {
45574         if (typeof a === 'boolean') {
45575           utf8 = a;
45576         }
45577         return this;
45578       };
45579
45580       // private methods
45581
45582       /**
45583        * Calculate the MD5 of a raw string
45584        */
45585
45586       function rstr(s) {
45587         s = (utf8) ? utf8Encode(s) : s;
45588         return binl2rstr(binl(rstr2binl(s), s.length * 8));
45589       }
45590
45591       /**
45592        * Calculate the HMAC-MD5, of a key and some data (raw strings)
45593        */
45594
45595       function rstr_hmac(key, data) {
45596         var bkey, ipad, opad, hash, i;
45597
45598         key = (utf8) ? utf8Encode(key) : key;
45599         data = (utf8) ? utf8Encode(data) : data;
45600         bkey = rstr2binl(key);
45601         if (bkey.length > 16) {
45602           bkey = binl(bkey, key.length * 8);
45603         }
45604
45605         ipad = Array(16), opad = Array(16);
45606         for (i = 0; i < 16; i += 1) {
45607           ipad[i] = bkey[i] ^ 0x36363636;
45608           opad[i] = bkey[i] ^ 0x5C5C5C5C;
45609         }
45610         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
45611         return binl2rstr(binl(opad.concat(hash), 512 + 128));
45612       }
45613
45614       /**
45615        * Calculate the MD5 of an array of little-endian words, and a bit length.
45616        */
45617
45618       function binl(x, len) {
45619         var i, olda, oldb, oldc, oldd,
45620           a = 1732584193,
45621           b = -271733879,
45622           c = -1732584194,
45623           d = 271733878;
45624
45625         /* append padding */
45626         x[len >> 5] |= 0x80 << ((len) % 32);
45627         x[(((len + 64) >>> 9) << 4) + 14] = len;
45628
45629         for (i = 0; i < x.length; i += 16) {
45630           olda = a;
45631           oldb = b;
45632           oldc = c;
45633           oldd = d;
45634
45635           a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
45636           d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
45637           c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
45638           b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
45639           a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
45640           d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
45641           c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
45642           b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
45643           a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
45644           d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
45645           c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
45646           b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
45647           a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
45648           d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
45649           c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
45650           b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
45651
45652           a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
45653           d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
45654           c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
45655           b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
45656           a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
45657           d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
45658           c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
45659           b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
45660           a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
45661           d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
45662           c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
45663           b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
45664           a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
45665           d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
45666           c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
45667           b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
45668
45669           a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
45670           d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
45671           c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
45672           b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
45673           a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
45674           d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
45675           c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
45676           b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
45677           a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
45678           d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
45679           c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
45680           b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
45681           a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
45682           d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
45683           c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
45684           b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
45685
45686           a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
45687           d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
45688           c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
45689           b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
45690           a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
45691           d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
45692           c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
45693           b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
45694           a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
45695           d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
45696           c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
45697           b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
45698           a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
45699           d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
45700           c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
45701           b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
45702
45703           a = safe_add(a, olda);
45704           b = safe_add(b, oldb);
45705           c = safe_add(c, oldc);
45706           d = safe_add(d, oldd);
45707         }
45708         return Array(a, b, c, d);
45709       }
45710
45711       /**
45712        * These functions implement the four basic operations the algorithm uses.
45713        */
45714
45715       function md5_cmn(q, a, b, x, s, t) {
45716         return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
45717       }
45718
45719       function md5_ff(a, b, c, d, x, s, t) {
45720         return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
45721       }
45722
45723       function md5_gg(a, b, c, d, x, s, t) {
45724         return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
45725       }
45726
45727       function md5_hh(a, b, c, d, x, s, t) {
45728         return md5_cmn(b ^ c ^ d, a, b, x, s, t);
45729       }
45730
45731       function md5_ii(a, b, c, d, x, s, t) {
45732         return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
45733       }
45734     },
45735     /**
45736      * @member Hashes
45737      * @class Hashes.SHA1
45738      * @param {Object} [config]
45739      * @constructor
45740      *
45741      * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
45742      * Version 2.2 Copyright Paul Johnston 2000 - 2009.
45743      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45744      * See http://pajhome.org.uk/crypt/md5 for details.
45745      */
45746     SHA1: function(options) {
45747       /**
45748        * Private config properties. You may need to tweak these to be compatible with
45749        * the server-side, but the defaults work in most cases.
45750        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
45751        */
45752       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
45753         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
45754         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
45755
45756       // public methods
45757       this.hex = function(s) {
45758         return rstr2hex(rstr(s, utf8), hexcase);
45759       };
45760       this.b64 = function(s) {
45761         return rstr2b64(rstr(s, utf8), b64pad);
45762       };
45763       this.any = function(s, e) {
45764         return rstr2any(rstr(s, utf8), e);
45765       };
45766       this.raw = function(s) {
45767         return rstr(s, utf8);
45768       };
45769       this.hex_hmac = function(k, d) {
45770         return rstr2hex(rstr_hmac(k, d));
45771       };
45772       this.b64_hmac = function(k, d) {
45773         return rstr2b64(rstr_hmac(k, d), b64pad);
45774       };
45775       this.any_hmac = function(k, d, e) {
45776         return rstr2any(rstr_hmac(k, d), e);
45777       };
45778       /**
45779        * Perform a simple self-test to see if the VM is working
45780        * @return {String} Hexadecimal hash sample
45781        * @public
45782        */
45783       this.vm_test = function() {
45784         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45785       };
45786       /**
45787        * @description Enable/disable uppercase hexadecimal returned string
45788        * @param {boolean}
45789        * @return {Object} this
45790        * @public
45791        */
45792       this.setUpperCase = function(a) {
45793         if (typeof a === 'boolean') {
45794           hexcase = a;
45795         }
45796         return this;
45797       };
45798       /**
45799        * @description Defines a base64 pad string
45800        * @param {string} Pad
45801        * @return {Object} this
45802        * @public
45803        */
45804       this.setPad = function(a) {
45805         b64pad = a || b64pad;
45806         return this;
45807       };
45808       /**
45809        * @description Defines a base64 pad string
45810        * @param {boolean}
45811        * @return {Object} this
45812        * @public
45813        */
45814       this.setUTF8 = function(a) {
45815         if (typeof a === 'boolean') {
45816           utf8 = a;
45817         }
45818         return this;
45819       };
45820
45821       // private methods
45822
45823       /**
45824        * Calculate the SHA-512 of a raw string
45825        */
45826
45827       function rstr(s) {
45828         s = (utf8) ? utf8Encode(s) : s;
45829         return binb2rstr(binb(rstr2binb(s), s.length * 8));
45830       }
45831
45832       /**
45833        * Calculate the HMAC-SHA1 of a key and some data (raw strings)
45834        */
45835
45836       function rstr_hmac(key, data) {
45837         var bkey, ipad, opad, i, hash;
45838         key = (utf8) ? utf8Encode(key) : key;
45839         data = (utf8) ? utf8Encode(data) : data;
45840         bkey = rstr2binb(key);
45841
45842         if (bkey.length > 16) {
45843           bkey = binb(bkey, key.length * 8);
45844         }
45845         ipad = Array(16), opad = Array(16);
45846         for (i = 0; i < 16; i += 1) {
45847           ipad[i] = bkey[i] ^ 0x36363636;
45848           opad[i] = bkey[i] ^ 0x5C5C5C5C;
45849         }
45850         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
45851         return binb2rstr(binb(opad.concat(hash), 512 + 160));
45852       }
45853
45854       /**
45855        * Calculate the SHA-1 of an array of big-endian words, and a bit length
45856        */
45857
45858       function binb(x, len) {
45859         var i, j, t, olda, oldb, oldc, oldd, olde,
45860           w = Array(80),
45861           a = 1732584193,
45862           b = -271733879,
45863           c = -1732584194,
45864           d = 271733878,
45865           e = -1009589776;
45866
45867         /* append padding */
45868         x[len >> 5] |= 0x80 << (24 - len % 32);
45869         x[((len + 64 >> 9) << 4) + 15] = len;
45870
45871         for (i = 0; i < x.length; i += 16) {
45872           olda = a;
45873           oldb = b;
45874           oldc = c;
45875           oldd = d;
45876           olde = e;
45877
45878           for (j = 0; j < 80; j += 1) {
45879             if (j < 16) {
45880               w[j] = x[i + j];
45881             } else {
45882               w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
45883             }
45884             t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
45885               safe_add(safe_add(e, w[j]), sha1_kt(j)));
45886             e = d;
45887             d = c;
45888             c = bit_rol(b, 30);
45889             b = a;
45890             a = t;
45891           }
45892
45893           a = safe_add(a, olda);
45894           b = safe_add(b, oldb);
45895           c = safe_add(c, oldc);
45896           d = safe_add(d, oldd);
45897           e = safe_add(e, olde);
45898         }
45899         return Array(a, b, c, d, e);
45900       }
45901
45902       /**
45903        * Perform the appropriate triplet combination function for the current
45904        * iteration
45905        */
45906
45907       function sha1_ft(t, b, c, d) {
45908         if (t < 20) {
45909           return (b & c) | ((~b) & d);
45910         }
45911         if (t < 40) {
45912           return b ^ c ^ d;
45913         }
45914         if (t < 60) {
45915           return (b & c) | (b & d) | (c & d);
45916         }
45917         return b ^ c ^ d;
45918       }
45919
45920       /**
45921        * Determine the appropriate additive constant for the current iteration
45922        */
45923
45924       function sha1_kt(t) {
45925         return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
45926           (t < 60) ? -1894007588 : -899497514;
45927       }
45928     },
45929     /**
45930      * @class Hashes.SHA256
45931      * @param {config}
45932      *
45933      * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
45934      * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
45935      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45936      * See http://pajhome.org.uk/crypt/md5 for details.
45937      * Also http://anmar.eu.org/projects/jssha2/
45938      */
45939     SHA256: function(options) {
45940       /**
45941        * Private properties configuration variables. You may need to tweak these to be compatible with
45942        * the server-side, but the defaults work in most cases.
45943        * @see this.setUpperCase() method
45944        * @see this.setPad() method
45945        */
45946       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase  */
45947         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
45948         /* base-64 pad character. Default '=' for strict RFC compliance   */
45949         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45950         /* enable/disable utf8 encoding */
45951         sha256_K;
45952
45953       /* privileged (public) methods */
45954       this.hex = function(s) {
45955         return rstr2hex(rstr(s, utf8));
45956       };
45957       this.b64 = function(s) {
45958         return rstr2b64(rstr(s, utf8), b64pad);
45959       };
45960       this.any = function(s, e) {
45961         return rstr2any(rstr(s, utf8), e);
45962       };
45963       this.raw = function(s) {
45964         return rstr(s, utf8);
45965       };
45966       this.hex_hmac = function(k, d) {
45967         return rstr2hex(rstr_hmac(k, d));
45968       };
45969       this.b64_hmac = function(k, d) {
45970         return rstr2b64(rstr_hmac(k, d), b64pad);
45971       };
45972       this.any_hmac = function(k, d, e) {
45973         return rstr2any(rstr_hmac(k, d), e);
45974       };
45975       /**
45976        * Perform a simple self-test to see if the VM is working
45977        * @return {String} Hexadecimal hash sample
45978        * @public
45979        */
45980       this.vm_test = function() {
45981         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45982       };
45983       /**
45984        * Enable/disable uppercase hexadecimal returned string
45985        * @param {boolean}
45986        * @return {Object} this
45987        * @public
45988        */
45989       this.setUpperCase = function(a) {
45990         if (typeof a === 'boolean') {
45991           hexcase = a;
45992         }
45993         return this;
45994       };
45995       /**
45996        * @description Defines a base64 pad string
45997        * @param {string} Pad
45998        * @return {Object} this
45999        * @public
46000        */
46001       this.setPad = function(a) {
46002         b64pad = a || b64pad;
46003         return this;
46004       };
46005       /**
46006        * Defines a base64 pad string
46007        * @param {boolean}
46008        * @return {Object} this
46009        * @public
46010        */
46011       this.setUTF8 = function(a) {
46012         if (typeof a === 'boolean') {
46013           utf8 = a;
46014         }
46015         return this;
46016       };
46017
46018       // private methods
46019
46020       /**
46021        * Calculate the SHA-512 of a raw string
46022        */
46023
46024       function rstr(s, utf8) {
46025         s = (utf8) ? utf8Encode(s) : s;
46026         return binb2rstr(binb(rstr2binb(s), s.length * 8));
46027       }
46028
46029       /**
46030        * Calculate the HMAC-sha256 of a key and some data (raw strings)
46031        */
46032
46033       function rstr_hmac(key, data) {
46034         key = (utf8) ? utf8Encode(key) : key;
46035         data = (utf8) ? utf8Encode(data) : data;
46036         var hash, i = 0,
46037           bkey = rstr2binb(key),
46038           ipad = Array(16),
46039           opad = Array(16);
46040
46041         if (bkey.length > 16) {
46042           bkey = binb(bkey, key.length * 8);
46043         }
46044
46045         for (; i < 16; i += 1) {
46046           ipad[i] = bkey[i] ^ 0x36363636;
46047           opad[i] = bkey[i] ^ 0x5C5C5C5C;
46048         }
46049
46050         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
46051         return binb2rstr(binb(opad.concat(hash), 512 + 256));
46052       }
46053
46054       /*
46055        * Main sha256 function, with its support functions
46056        */
46057
46058       function sha256_S(X, n) {
46059         return (X >>> n) | (X << (32 - n));
46060       }
46061
46062       function sha256_R(X, n) {
46063         return (X >>> n);
46064       }
46065
46066       function sha256_Ch(x, y, z) {
46067         return ((x & y) ^ ((~x) & z));
46068       }
46069
46070       function sha256_Maj(x, y, z) {
46071         return ((x & y) ^ (x & z) ^ (y & z));
46072       }
46073
46074       function sha256_Sigma0256(x) {
46075         return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
46076       }
46077
46078       function sha256_Sigma1256(x) {
46079         return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
46080       }
46081
46082       function sha256_Gamma0256(x) {
46083         return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
46084       }
46085
46086       function sha256_Gamma1256(x) {
46087         return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
46088       }
46089
46090       sha256_K = [
46091         1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
46092         1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
46093         264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
46094         113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
46095         1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
46096         430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
46097         1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
46098       ];
46099
46100       function binb(m, l) {
46101         var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
46102           1359893119, -1694144372, 528734635, 1541459225
46103         ];
46104         var W = new Array(64);
46105         var a, b, c, d, e, f, g, h;
46106         var i, j, T1, T2;
46107
46108         /* append padding */
46109         m[l >> 5] |= 0x80 << (24 - l % 32);
46110         m[((l + 64 >> 9) << 4) + 15] = l;
46111
46112         for (i = 0; i < m.length; i += 16) {
46113           a = HASH[0];
46114           b = HASH[1];
46115           c = HASH[2];
46116           d = HASH[3];
46117           e = HASH[4];
46118           f = HASH[5];
46119           g = HASH[6];
46120           h = HASH[7];
46121
46122           for (j = 0; j < 64; j += 1) {
46123             if (j < 16) {
46124               W[j] = m[j + i];
46125             } else {
46126               W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
46127                 sha256_Gamma0256(W[j - 15])), W[j - 16]);
46128             }
46129
46130             T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
46131               sha256_K[j]), W[j]);
46132             T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
46133             h = g;
46134             g = f;
46135             f = e;
46136             e = safe_add(d, T1);
46137             d = c;
46138             c = b;
46139             b = a;
46140             a = safe_add(T1, T2);
46141           }
46142
46143           HASH[0] = safe_add(a, HASH[0]);
46144           HASH[1] = safe_add(b, HASH[1]);
46145           HASH[2] = safe_add(c, HASH[2]);
46146           HASH[3] = safe_add(d, HASH[3]);
46147           HASH[4] = safe_add(e, HASH[4]);
46148           HASH[5] = safe_add(f, HASH[5]);
46149           HASH[6] = safe_add(g, HASH[6]);
46150           HASH[7] = safe_add(h, HASH[7]);
46151         }
46152         return HASH;
46153       }
46154
46155     },
46156
46157     /**
46158      * @class Hashes.SHA512
46159      * @param {config}
46160      *
46161      * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
46162      * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
46163      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
46164      * See http://pajhome.org.uk/crypt/md5 for details.
46165      */
46166     SHA512: function(options) {
46167       /**
46168        * Private properties configuration variables. You may need to tweak these to be compatible with
46169        * the server-side, but the defaults work in most cases.
46170        * @see this.setUpperCase() method
46171        * @see this.setPad() method
46172        */
46173       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
46174         /* hexadecimal output case format. false - lowercase; true - uppercase  */
46175         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
46176         /* base-64 pad character. Default '=' for strict RFC compliance   */
46177         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
46178         /* enable/disable utf8 encoding */
46179         sha512_k;
46180
46181       /* privileged (public) methods */
46182       this.hex = function(s) {
46183         return rstr2hex(rstr(s));
46184       };
46185       this.b64 = function(s) {
46186         return rstr2b64(rstr(s), b64pad);
46187       };
46188       this.any = function(s, e) {
46189         return rstr2any(rstr(s), e);
46190       };
46191       this.raw = function(s) {
46192         return rstr(s, utf8);
46193       };
46194       this.hex_hmac = function(k, d) {
46195         return rstr2hex(rstr_hmac(k, d));
46196       };
46197       this.b64_hmac = function(k, d) {
46198         return rstr2b64(rstr_hmac(k, d), b64pad);
46199       };
46200       this.any_hmac = function(k, d, e) {
46201         return rstr2any(rstr_hmac(k, d), e);
46202       };
46203       /**
46204        * Perform a simple self-test to see if the VM is working
46205        * @return {String} Hexadecimal hash sample
46206        * @public
46207        */
46208       this.vm_test = function() {
46209         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
46210       };
46211       /**
46212        * @description Enable/disable uppercase hexadecimal returned string
46213        * @param {boolean}
46214        * @return {Object} this
46215        * @public
46216        */
46217       this.setUpperCase = function(a) {
46218         if (typeof a === 'boolean') {
46219           hexcase = a;
46220         }
46221         return this;
46222       };
46223       /**
46224        * @description Defines a base64 pad string
46225        * @param {string} Pad
46226        * @return {Object} this
46227        * @public
46228        */
46229       this.setPad = function(a) {
46230         b64pad = a || b64pad;
46231         return this;
46232       };
46233       /**
46234        * @description Defines a base64 pad string
46235        * @param {boolean}
46236        * @return {Object} this
46237        * @public
46238        */
46239       this.setUTF8 = function(a) {
46240         if (typeof a === 'boolean') {
46241           utf8 = a;
46242         }
46243         return this;
46244       };
46245
46246       /* private methods */
46247
46248       /**
46249        * Calculate the SHA-512 of a raw string
46250        */
46251
46252       function rstr(s) {
46253         s = (utf8) ? utf8Encode(s) : s;
46254         return binb2rstr(binb(rstr2binb(s), s.length * 8));
46255       }
46256       /*
46257        * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
46258        */
46259
46260       function rstr_hmac(key, data) {
46261         key = (utf8) ? utf8Encode(key) : key;
46262         data = (utf8) ? utf8Encode(data) : data;
46263
46264         var hash, i = 0,
46265           bkey = rstr2binb(key),
46266           ipad = Array(32),
46267           opad = Array(32);
46268
46269         if (bkey.length > 32) {
46270           bkey = binb(bkey, key.length * 8);
46271         }
46272
46273         for (; i < 32; i += 1) {
46274           ipad[i] = bkey[i] ^ 0x36363636;
46275           opad[i] = bkey[i] ^ 0x5C5C5C5C;
46276         }
46277
46278         hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
46279         return binb2rstr(binb(opad.concat(hash), 1024 + 512));
46280       }
46281
46282       /**
46283        * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
46284        */
46285
46286       function binb(x, len) {
46287         var j, i, l,
46288           W = new Array(80),
46289           hash = new Array(16),
46290           //Initial hash values
46291           H = [
46292             new int64(0x6a09e667, -205731576),
46293             new int64(-1150833019, -2067093701),
46294             new int64(0x3c6ef372, -23791573),
46295             new int64(-1521486534, 0x5f1d36f1),
46296             new int64(0x510e527f, -1377402159),
46297             new int64(-1694144372, 0x2b3e6c1f),
46298             new int64(0x1f83d9ab, -79577749),
46299             new int64(0x5be0cd19, 0x137e2179)
46300           ],
46301           T1 = new int64(0, 0),
46302           T2 = new int64(0, 0),
46303           a = new int64(0, 0),
46304           b = new int64(0, 0),
46305           c = new int64(0, 0),
46306           d = new int64(0, 0),
46307           e = new int64(0, 0),
46308           f = new int64(0, 0),
46309           g = new int64(0, 0),
46310           h = new int64(0, 0),
46311           //Temporary variables not specified by the document
46312           s0 = new int64(0, 0),
46313           s1 = new int64(0, 0),
46314           Ch = new int64(0, 0),
46315           Maj = new int64(0, 0),
46316           r1 = new int64(0, 0),
46317           r2 = new int64(0, 0),
46318           r3 = new int64(0, 0);
46319
46320         if (sha512_k === undefined) {
46321           //SHA512 constants
46322           sha512_k = [
46323             new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
46324             new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
46325             new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
46326             new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
46327             new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
46328             new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
46329             new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
46330             new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
46331             new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
46332             new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
46333             new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
46334             new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
46335             new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
46336             new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
46337             new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
46338             new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
46339             new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
46340             new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
46341             new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
46342             new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
46343             new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
46344             new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
46345             new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
46346             new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
46347             new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
46348             new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
46349             new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
46350             new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
46351             new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
46352             new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
46353             new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
46354             new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
46355             new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
46356             new int64(-354779690, -840897762), new int64(-176337025, -294727304),
46357             new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
46358             new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
46359             new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
46360             new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
46361             new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
46362             new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
46363           ];
46364         }
46365
46366         for (i = 0; i < 80; i += 1) {
46367           W[i] = new int64(0, 0);
46368         }
46369
46370         // append padding to the source string. The format is described in the FIPS.
46371         x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
46372         x[((len + 128 >> 10) << 5) + 31] = len;
46373         l = x.length;
46374         for (i = 0; i < l; i += 32) { //32 dwords is the block size
46375           int64copy(a, H[0]);
46376           int64copy(b, H[1]);
46377           int64copy(c, H[2]);
46378           int64copy(d, H[3]);
46379           int64copy(e, H[4]);
46380           int64copy(f, H[5]);
46381           int64copy(g, H[6]);
46382           int64copy(h, H[7]);
46383
46384           for (j = 0; j < 16; j += 1) {
46385             W[j].h = x[i + 2 * j];
46386             W[j].l = x[i + 2 * j + 1];
46387           }
46388
46389           for (j = 16; j < 80; j += 1) {
46390             //sigma1
46391             int64rrot(r1, W[j - 2], 19);
46392             int64revrrot(r2, W[j - 2], 29);
46393             int64shr(r3, W[j - 2], 6);
46394             s1.l = r1.l ^ r2.l ^ r3.l;
46395             s1.h = r1.h ^ r2.h ^ r3.h;
46396             //sigma0
46397             int64rrot(r1, W[j - 15], 1);
46398             int64rrot(r2, W[j - 15], 8);
46399             int64shr(r3, W[j - 15], 7);
46400             s0.l = r1.l ^ r2.l ^ r3.l;
46401             s0.h = r1.h ^ r2.h ^ r3.h;
46402
46403             int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
46404           }
46405
46406           for (j = 0; j < 80; j += 1) {
46407             //Ch
46408             Ch.l = (e.l & f.l) ^ (~e.l & g.l);
46409             Ch.h = (e.h & f.h) ^ (~e.h & g.h);
46410
46411             //Sigma1
46412             int64rrot(r1, e, 14);
46413             int64rrot(r2, e, 18);
46414             int64revrrot(r3, e, 9);
46415             s1.l = r1.l ^ r2.l ^ r3.l;
46416             s1.h = r1.h ^ r2.h ^ r3.h;
46417
46418             //Sigma0
46419             int64rrot(r1, a, 28);
46420             int64revrrot(r2, a, 2);
46421             int64revrrot(r3, a, 7);
46422             s0.l = r1.l ^ r2.l ^ r3.l;
46423             s0.h = r1.h ^ r2.h ^ r3.h;
46424
46425             //Maj
46426             Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
46427             Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
46428
46429             int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
46430             int64add(T2, s0, Maj);
46431
46432             int64copy(h, g);
46433             int64copy(g, f);
46434             int64copy(f, e);
46435             int64add(e, d, T1);
46436             int64copy(d, c);
46437             int64copy(c, b);
46438             int64copy(b, a);
46439             int64add(a, T1, T2);
46440           }
46441           int64add(H[0], H[0], a);
46442           int64add(H[1], H[1], b);
46443           int64add(H[2], H[2], c);
46444           int64add(H[3], H[3], d);
46445           int64add(H[4], H[4], e);
46446           int64add(H[5], H[5], f);
46447           int64add(H[6], H[6], g);
46448           int64add(H[7], H[7], h);
46449         }
46450
46451         //represent the hash as an array of 32-bit dwords
46452         for (i = 0; i < 8; i += 1) {
46453           hash[2 * i] = H[i].h;
46454           hash[2 * i + 1] = H[i].l;
46455         }
46456         return hash;
46457       }
46458
46459       //A constructor for 64-bit numbers
46460
46461       function int64(h, l) {
46462         this.h = h;
46463         this.l = l;
46464         //this.toString = int64toString;
46465       }
46466
46467       //Copies src into dst, assuming both are 64-bit numbers
46468
46469       function int64copy(dst, src) {
46470         dst.h = src.h;
46471         dst.l = src.l;
46472       }
46473
46474       //Right-rotates a 64-bit number by shift
46475       //Won't handle cases of shift>=32
46476       //The function revrrot() is for that
46477
46478       function int64rrot(dst, x, shift) {
46479         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
46480         dst.h = (x.h >>> shift) | (x.l << (32 - shift));
46481       }
46482
46483       //Reverses the dwords of the source and then rotates right by shift.
46484       //This is equivalent to rotation by 32+shift
46485
46486       function int64revrrot(dst, x, shift) {
46487         dst.l = (x.h >>> shift) | (x.l << (32 - shift));
46488         dst.h = (x.l >>> shift) | (x.h << (32 - shift));
46489       }
46490
46491       //Bitwise-shifts right a 64-bit number by shift
46492       //Won't handle shift>=32, but it's never needed in SHA512
46493
46494       function int64shr(dst, x, shift) {
46495         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
46496         dst.h = (x.h >>> shift);
46497       }
46498
46499       //Adds two 64-bit numbers
46500       //Like the original implementation, does not rely on 32-bit operations
46501
46502       function int64add(dst, x, y) {
46503         var w0 = (x.l & 0xffff) + (y.l & 0xffff);
46504         var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
46505         var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
46506         var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
46507         dst.l = (w0 & 0xffff) | (w1 << 16);
46508         dst.h = (w2 & 0xffff) | (w3 << 16);
46509       }
46510
46511       //Same, except with 4 addends. Works faster than adding them one by one.
46512
46513       function int64add4(dst, a, b, c, d) {
46514         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
46515         var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
46516         var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
46517         var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
46518         dst.l = (w0 & 0xffff) | (w1 << 16);
46519         dst.h = (w2 & 0xffff) | (w3 << 16);
46520       }
46521
46522       //Same, except with 5 addends
46523
46524       function int64add5(dst, a, b, c, d, e) {
46525         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
46526           w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
46527           w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
46528           w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
46529         dst.l = (w0 & 0xffff) | (w1 << 16);
46530         dst.h = (w2 & 0xffff) | (w3 << 16);
46531       }
46532     },
46533     /**
46534      * @class Hashes.RMD160
46535      * @constructor
46536      * @param {Object} [config]
46537      *
46538      * A JavaScript implementation of the RIPEMD-160 Algorithm
46539      * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
46540      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
46541      * See http://pajhome.org.uk/crypt/md5 for details.
46542      * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
46543      */
46544     RMD160: function(options) {
46545       /**
46546        * Private properties configuration variables. You may need to tweak these to be compatible with
46547        * the server-side, but the defaults work in most cases.
46548        * @see this.setUpperCase() method
46549        * @see this.setPad() method
46550        */
46551       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
46552         /* hexadecimal output case format. false - lowercase; true - uppercase  */
46553         b64pad = (options && typeof options.pad === 'string') ? options.pa : '=',
46554         /* base-64 pad character. Default '=' for strict RFC compliance   */
46555         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
46556         /* enable/disable utf8 encoding */
46557         rmd160_r1 = [
46558           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
46559           7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
46560           3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
46561           1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
46562           4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
46563         ],
46564         rmd160_r2 = [
46565           5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
46566           6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
46567           15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
46568           8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
46569           12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
46570         ],
46571         rmd160_s1 = [
46572           11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
46573           7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
46574           11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
46575           11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
46576           9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
46577         ],
46578         rmd160_s2 = [
46579           8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
46580           9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
46581           9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
46582           15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
46583           8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
46584         ];
46585
46586       /* privileged (public) methods */
46587       this.hex = function(s) {
46588         return rstr2hex(rstr(s, utf8));
46589       };
46590       this.b64 = function(s) {
46591         return rstr2b64(rstr(s, utf8), b64pad);
46592       };
46593       this.any = function(s, e) {
46594         return rstr2any(rstr(s, utf8), e);
46595       };
46596       this.raw = function(s) {
46597         return rstr(s, utf8);
46598       };
46599       this.hex_hmac = function(k, d) {
46600         return rstr2hex(rstr_hmac(k, d));
46601       };
46602       this.b64_hmac = function(k, d) {
46603         return rstr2b64(rstr_hmac(k, d), b64pad);
46604       };
46605       this.any_hmac = function(k, d, e) {
46606         return rstr2any(rstr_hmac(k, d), e);
46607       };
46608       /**
46609        * Perform a simple self-test to see if the VM is working
46610        * @return {String} Hexadecimal hash sample
46611        * @public
46612        */
46613       this.vm_test = function() {
46614         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
46615       };
46616       /**
46617        * @description Enable/disable uppercase hexadecimal returned string
46618        * @param {boolean}
46619        * @return {Object} this
46620        * @public
46621        */
46622       this.setUpperCase = function(a) {
46623         if (typeof a === 'boolean') {
46624           hexcase = a;
46625         }
46626         return this;
46627       };
46628       /**
46629        * @description Defines a base64 pad string
46630        * @param {string} Pad
46631        * @return {Object} this
46632        * @public
46633        */
46634       this.setPad = function(a) {
46635         if (typeof a !== 'undefined') {
46636           b64pad = a;
46637         }
46638         return this;
46639       };
46640       /**
46641        * @description Defines a base64 pad string
46642        * @param {boolean}
46643        * @return {Object} this
46644        * @public
46645        */
46646       this.setUTF8 = function(a) {
46647         if (typeof a === 'boolean') {
46648           utf8 = a;
46649         }
46650         return this;
46651       };
46652
46653       /* private methods */
46654
46655       /**
46656        * Calculate the rmd160 of a raw string
46657        */
46658
46659       function rstr(s) {
46660         s = (utf8) ? utf8Encode(s) : s;
46661         return binl2rstr(binl(rstr2binl(s), s.length * 8));
46662       }
46663
46664       /**
46665        * Calculate the HMAC-rmd160 of a key and some data (raw strings)
46666        */
46667
46668       function rstr_hmac(key, data) {
46669         key = (utf8) ? utf8Encode(key) : key;
46670         data = (utf8) ? utf8Encode(data) : data;
46671         var i, hash,
46672           bkey = rstr2binl(key),
46673           ipad = Array(16),
46674           opad = Array(16);
46675
46676         if (bkey.length > 16) {
46677           bkey = binl(bkey, key.length * 8);
46678         }
46679
46680         for (i = 0; i < 16; i += 1) {
46681           ipad[i] = bkey[i] ^ 0x36363636;
46682           opad[i] = bkey[i] ^ 0x5C5C5C5C;
46683         }
46684         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
46685         return binl2rstr(binl(opad.concat(hash), 512 + 160));
46686       }
46687
46688       /**
46689        * Convert an array of little-endian words to a string
46690        */
46691
46692       function binl2rstr(input) {
46693         var i, output = '',
46694           l = input.length * 32;
46695         for (i = 0; i < l; i += 8) {
46696           output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
46697         }
46698         return output;
46699       }
46700
46701       /**
46702        * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
46703        */
46704
46705       function binl(x, len) {
46706         var T, j, i, l,
46707           h0 = 0x67452301,
46708           h1 = 0xefcdab89,
46709           h2 = 0x98badcfe,
46710           h3 = 0x10325476,
46711           h4 = 0xc3d2e1f0,
46712           A1, B1, C1, D1, E1,
46713           A2, B2, C2, D2, E2;
46714
46715         /* append padding */
46716         x[len >> 5] |= 0x80 << (len % 32);
46717         x[(((len + 64) >>> 9) << 4) + 14] = len;
46718         l = x.length;
46719
46720         for (i = 0; i < l; i += 16) {
46721           A1 = A2 = h0;
46722           B1 = B2 = h1;
46723           C1 = C2 = h2;
46724           D1 = D2 = h3;
46725           E1 = E2 = h4;
46726           for (j = 0; j <= 79; j += 1) {
46727             T = safe_add(A1, rmd160_f(j, B1, C1, D1));
46728             T = safe_add(T, x[i + rmd160_r1[j]]);
46729             T = safe_add(T, rmd160_K1(j));
46730             T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
46731             A1 = E1;
46732             E1 = D1;
46733             D1 = bit_rol(C1, 10);
46734             C1 = B1;
46735             B1 = T;
46736             T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
46737             T = safe_add(T, x[i + rmd160_r2[j]]);
46738             T = safe_add(T, rmd160_K2(j));
46739             T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
46740             A2 = E2;
46741             E2 = D2;
46742             D2 = bit_rol(C2, 10);
46743             C2 = B2;
46744             B2 = T;
46745           }
46746
46747           T = safe_add(h1, safe_add(C1, D2));
46748           h1 = safe_add(h2, safe_add(D1, E2));
46749           h2 = safe_add(h3, safe_add(E1, A2));
46750           h3 = safe_add(h4, safe_add(A1, B2));
46751           h4 = safe_add(h0, safe_add(B1, C2));
46752           h0 = T;
46753         }
46754         return [h0, h1, h2, h3, h4];
46755       }
46756
46757       // specific algorithm methods
46758
46759       function rmd160_f(j, x, y, z) {
46760         return (0 <= j && j <= 15) ? (x ^ y ^ z) :
46761           (16 <= j && j <= 31) ? (x & y) | (~x & z) :
46762           (32 <= j && j <= 47) ? (x | ~y) ^ z :
46763           (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
46764           (64 <= j && j <= 79) ? x ^ (y | ~z) :
46765           'rmd160_f: j out of range';
46766       }
46767
46768       function rmd160_K1(j) {
46769         return (0 <= j && j <= 15) ? 0x00000000 :
46770           (16 <= j && j <= 31) ? 0x5a827999 :
46771           (32 <= j && j <= 47) ? 0x6ed9eba1 :
46772           (48 <= j && j <= 63) ? 0x8f1bbcdc :
46773           (64 <= j && j <= 79) ? 0xa953fd4e :
46774           'rmd160_K1: j out of range';
46775       }
46776
46777       function rmd160_K2(j) {
46778         return (0 <= j && j <= 15) ? 0x50a28be6 :
46779           (16 <= j && j <= 31) ? 0x5c4dd124 :
46780           (32 <= j && j <= 47) ? 0x6d703ef3 :
46781           (48 <= j && j <= 63) ? 0x7a6d76e9 :
46782           (64 <= j && j <= 79) ? 0x00000000 :
46783           'rmd160_K2: j out of range';
46784       }
46785     }
46786   };
46787
46788   // exposes Hashes
46789   (function(window, undefined) {
46790     var freeExports = false;
46791     {
46792       freeExports = exports;
46793       if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
46794         window = commonjsGlobal;
46795       }
46796     }
46797
46798     if (typeof undefined === 'function' && typeof undefined.amd === 'object' && undefined.amd) {
46799       // define as an anonymous module, so, through path mapping, it can be aliased
46800       undefined(function() {
46801         return Hashes;
46802       });
46803     } else if (freeExports) {
46804       // in Node.js or RingoJS v0.8.0+
46805       if ('object' === 'object' && module && module.exports === freeExports) {
46806         module.exports = Hashes;
46807       }
46808       // in Narwhal or RingoJS v0.7.0-
46809       else {
46810         freeExports.Hashes = Hashes;
46811       }
46812     } else {
46813       // in a browser or Rhino
46814       window.Hashes = Hashes;
46815     }
46816   }(this));
46817 }()); // IIFE
46818 });
46819
46820 var immutable = extend$2;
46821
46822 var hasOwnProperty = Object.prototype.hasOwnProperty;
46823
46824 function extend$2() {
46825     var target = {};
46826
46827     for (var i = 0; i < arguments.length; i++) {
46828         var source = arguments[i];
46829
46830         for (var key in source) {
46831             if (hasOwnProperty.call(source, key)) {
46832                 target[key] = source[key];
46833             }
46834         }
46835     }
46836
46837     return target
46838 }
46839
46840 var sha1 = new hashes.SHA1();
46841
46842 var ohauth = {};
46843
46844 ohauth.qsString = function(obj) {
46845     return Object.keys(obj).sort().map(function(key) {
46846         return ohauth.percentEncode(key) + '=' +
46847             ohauth.percentEncode(obj[key]);
46848     }).join('&');
46849 };
46850
46851 ohauth.stringQs = function(str) {
46852     return str.split('&').filter(function (pair) {
46853         return pair !== '';
46854     }).reduce(function(obj, pair){
46855         var parts = pair.split('=');
46856         obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
46857             '' : decodeURIComponent(parts[1]);
46858         return obj;
46859     }, {});
46860 };
46861
46862 ohauth.rawxhr = function(method, url, data, headers, callback) {
46863     var xhr = new XMLHttpRequest(),
46864         twoHundred = /^20\d$/;
46865     xhr.onreadystatechange = function() {
46866         if (4 === xhr.readyState && 0 !== xhr.status) {
46867             if (twoHundred.test(xhr.status)) callback(null, xhr);
46868             else return callback(xhr, null);
46869         }
46870     };
46871     xhr.onerror = function(e) { return callback(e, null); };
46872     xhr.open(method, url, true);
46873     for (var h in headers) xhr.setRequestHeader(h, headers[h]);
46874     xhr.send(data);
46875     return xhr;
46876 };
46877
46878 ohauth.xhr = function(method, url, auth, data, options, callback) {
46879     var headers = (options && options.header) || {
46880         'Content-Type': 'application/x-www-form-urlencoded'
46881     };
46882     headers.Authorization = 'OAuth ' + ohauth.authHeader(auth);
46883     return ohauth.rawxhr(method, url, data, headers, callback);
46884 };
46885
46886 ohauth.nonce = function() {
46887     for (var o = ''; o.length < 6;) {
46888         o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
46889     }
46890     return o;
46891 };
46892
46893 ohauth.authHeader = function(obj) {
46894     return Object.keys(obj).sort().map(function(key) {
46895         return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
46896     }).join(', ');
46897 };
46898
46899 ohauth.timestamp = function() { return ~~((+new Date()) / 1000); };
46900
46901 ohauth.percentEncode = function(s) {
46902     return encodeURIComponent(s)
46903         .replace(/\!/g, '%21').replace(/\'/g, '%27')
46904         .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
46905 };
46906
46907 ohauth.baseString = function(method, url, params) {
46908     if (params.oauth_signature) delete params.oauth_signature;
46909     return [
46910         method,
46911         ohauth.percentEncode(url),
46912         ohauth.percentEncode(ohauth.qsString(params))].join('&');
46913 };
46914
46915 ohauth.signature = function(oauth_secret, token_secret, baseString) {
46916     return sha1.b64_hmac(
46917         ohauth.percentEncode(oauth_secret) + '&' +
46918         ohauth.percentEncode(token_secret),
46919         baseString);
46920 };
46921
46922 /**
46923  * Takes an options object for configuration (consumer_key,
46924  * consumer_secret, version, signature_method, token, token_secret)
46925  * and returns a function that generates the Authorization header
46926  * for given data.
46927  *
46928  * The returned function takes these parameters:
46929  * - method: GET/POST/...
46930  * - uri: full URI with protocol, port, path and query string
46931  * - extra_params: any extra parameters (that are passed in the POST data),
46932  *   can be an object or a from-urlencoded string.
46933  *
46934  * Returned function returns full OAuth header with "OAuth" string in it.
46935  */
46936
46937 ohauth.headerGenerator = function(options) {
46938     options = options || {};
46939     var consumer_key = options.consumer_key || '',
46940         consumer_secret = options.consumer_secret || '',
46941         signature_method = options.signature_method || 'HMAC-SHA1',
46942         version = options.version || '1.0',
46943         token = options.token || '',
46944         token_secret = options.token_secret || '';
46945
46946     return function(method, uri, extra_params) {
46947         method = method.toUpperCase();
46948         if (typeof extra_params === 'string' && extra_params.length > 0) {
46949             extra_params = ohauth.stringQs(extra_params);
46950         }
46951
46952         var uri_parts = uri.split('?', 2),
46953         base_uri = uri_parts[0];
46954
46955         var query_params = uri_parts.length === 2 ?
46956             ohauth.stringQs(uri_parts[1]) : {};
46957
46958         var oauth_params = {
46959             oauth_consumer_key: consumer_key,
46960             oauth_signature_method: signature_method,
46961             oauth_version: version,
46962             oauth_timestamp: ohauth.timestamp(),
46963             oauth_nonce: ohauth.nonce()
46964         };
46965
46966         if (token) oauth_params.oauth_token = token;
46967
46968         var all_params = immutable({}, oauth_params, query_params, extra_params),
46969             base_str = ohauth.baseString(method, base_uri, all_params);
46970
46971         oauth_params.oauth_signature = ohauth.signature(consumer_secret, token_secret, base_str);
46972
46973         return 'OAuth ' + ohauth.authHeader(oauth_params);
46974     };
46975 };
46976
46977 var index$13 = ohauth;
46978
46979 var resolveUrl = createCommonjsModule(function (module, exports) {
46980 // Copyright 2014 Simon Lydell
46981 // X11 (“MIT”) Licensed. (See LICENSE.)
46982
46983 void (function(root, factory) {
46984   if (typeof undefined === "function" && undefined.amd) {
46985     undefined(factory);
46986   } else {
46987     module.exports = factory();
46988   }
46989 }(commonjsGlobal, function() {
46990
46991   function resolveUrl(/* ...urls */) {
46992     var numUrls = arguments.length;
46993
46994     if (numUrls === 0) {
46995       throw new Error("resolveUrl requires at least one argument; got none.")
46996     }
46997
46998     var base = document.createElement("base");
46999     base.href = arguments[0];
47000
47001     if (numUrls === 1) {
47002       return base.href
47003     }
47004
47005     var head = document.getElementsByTagName("head")[0];
47006     head.insertBefore(base, head.firstChild);
47007
47008     var a = document.createElement("a");
47009     var resolved;
47010
47011     for (var index = 1; index < numUrls; index++) {
47012       a.href = arguments[index];
47013       resolved = a.href;
47014       base.href = resolved;
47015     }
47016
47017     head.removeChild(base);
47018
47019     return resolved
47020   }
47021
47022   return resolveUrl
47023
47024 }));
47025 });
47026
47027 var assign = make_assign();
47028 var create$2 = make_create();
47029 var trim = make_trim();
47030 var Global = (typeof window !== 'undefined' ? window : commonjsGlobal);
47031
47032 var util = {
47033         assign: assign,
47034         create: create$2,
47035         trim: trim,
47036         bind: bind$1,
47037         slice: slice$8,
47038         each: each$1,
47039         map: map$4,
47040         pluck: pluck$1,
47041         isList: isList$1,
47042         isFunction: isFunction$1,
47043         isObject: isObject$1,
47044         Global: Global
47045 };
47046
47047 function make_assign() {
47048         if (Object.assign) {
47049                 return Object.assign
47050         } else {
47051                 return function shimAssign(obj, props1, props2, etc) {
47052                         for (var i = 1; i < arguments.length; i++) {
47053                                 each$1(Object(arguments[i]), function(val, key) {
47054                                         obj[key] = val;
47055                                 });
47056                         }                       
47057                         return obj
47058                 }
47059         }
47060 }
47061
47062 function make_create() {
47063         if (Object.create) {
47064                 return function create(obj, assignProps1, assignProps2, etc) {
47065                         var assignArgsList = slice$8(arguments, 1);
47066                         return assign.apply(this, [Object.create(obj)].concat(assignArgsList))
47067                 }
47068         } else {
47069                 function F() {} // eslint-disable-line no-inner-declarations
47070                 return function create(obj, assignProps1, assignProps2, etc) {
47071                         var assignArgsList = slice$8(arguments, 1);
47072                         F.prototype = obj;
47073                         return assign.apply(this, [new F()].concat(assignArgsList))
47074                 }
47075         }
47076 }
47077
47078 function make_trim() {
47079         if (String.prototype.trim) {
47080                 return function trim(str) {
47081                         return String.prototype.trim.call(str)
47082                 }
47083         } else {
47084                 return function trim(str) {
47085                         return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
47086                 }
47087         }
47088 }
47089
47090 function bind$1(obj, fn) {
47091         return function() {
47092                 return fn.apply(obj, Array.prototype.slice.call(arguments, 0))
47093         }
47094 }
47095
47096 function slice$8(arr, index) {
47097         return Array.prototype.slice.call(arr, index || 0)
47098 }
47099
47100 function each$1(obj, fn) {
47101         pluck$1(obj, function(val, key) {
47102                 fn(val, key);
47103                 return false
47104         });
47105 }
47106
47107 function map$4(obj, fn) {
47108         var res = (isList$1(obj) ? [] : {});
47109         pluck$1(obj, function(v, k) {
47110                 res[k] = fn(v, k);
47111                 return false
47112         });
47113         return res
47114 }
47115
47116 function pluck$1(obj, fn) {
47117         if (isList$1(obj)) {
47118                 for (var i=0; i<obj.length; i++) {
47119                         if (fn(obj[i], i)) {
47120                                 return obj[i]
47121                         }
47122                 }
47123         } else {
47124                 for (var key in obj) {
47125                         if (obj.hasOwnProperty(key)) {
47126                                 if (fn(obj[key], key)) {
47127                                         return obj[key]
47128                                 }
47129                         }
47130                 }
47131         }
47132 }
47133
47134 function isList$1(val) {
47135         return (val != null && typeof val != 'function' && typeof val.length == 'number')
47136 }
47137
47138 function isFunction$1(val) {
47139         return val && {}.toString.call(val) === '[object Function]'
47140 }
47141
47142 function isObject$1(val) {
47143         return val && {}.toString.call(val) === '[object Object]'
47144 }
47145
47146 var slice$7 = util.slice;
47147 var pluck = util.pluck;
47148 var each = util.each;
47149 var bind = util.bind;
47150 var create$1 = util.create;
47151 var isList = util.isList;
47152 var isFunction = util.isFunction;
47153 var isObject = util.isObject;
47154
47155 var storeEngine = {
47156         createStore: createStore
47157 };
47158
47159 var storeAPI = {
47160         version: '2.0.12',
47161         enabled: false,
47162         
47163         // get returns the value of the given key. If that value
47164         // is undefined, it returns optionalDefaultValue instead.
47165         get: function(key, optionalDefaultValue) {
47166                 var data = this.storage.read(this._namespacePrefix + key);
47167                 return this._deserialize(data, optionalDefaultValue)
47168         },
47169
47170         // set will store the given value at key and returns value.
47171         // Calling set with value === undefined is equivalent to calling remove.
47172         set: function(key, value) {
47173                 if (value === undefined) {
47174                         return this.remove(key)
47175                 }
47176                 this.storage.write(this._namespacePrefix + key, this._serialize(value));
47177                 return value
47178         },
47179
47180         // remove deletes the key and value stored at the given key.
47181         remove: function(key) {
47182                 this.storage.remove(this._namespacePrefix + key);
47183         },
47184
47185         // each will call the given callback once for each key-value pair
47186         // in this store.
47187         each: function(callback) {
47188                 var self = this;
47189                 this.storage.each(function(val, namespacedKey) {
47190                         callback.call(self, self._deserialize(val), (namespacedKey || '').replace(self._namespaceRegexp, ''));
47191                 });
47192         },
47193
47194         // clearAll will remove all the stored key-value pairs in this store.
47195         clearAll: function() {
47196                 this.storage.clearAll();
47197         },
47198
47199         // additional functionality that can't live in plugins
47200         // ---------------------------------------------------
47201
47202         // hasNamespace returns true if this store instance has the given namespace.
47203         hasNamespace: function(namespace) {
47204                 return (this._namespacePrefix == '__storejs_'+namespace+'_')
47205         },
47206
47207         // createStore creates a store.js instance with the first
47208         // functioning storage in the list of storage candidates,
47209         // and applies the the given mixins to the instance.
47210         createStore: function() {
47211                 return createStore.apply(this, arguments)
47212         },
47213         
47214         addPlugin: function(plugin) {
47215                 this._addPlugin(plugin);
47216         },
47217         
47218         namespace: function(namespace) {
47219                 return createStore(this.storage, this.plugins, namespace)
47220         }
47221 };
47222
47223 function _warn() {
47224         var _console = (typeof console == 'undefined' ? null : console);
47225         if (!_console) { return }
47226         var fn = (_console.warn ? _console.warn : _console.log);
47227         fn.apply(_console, arguments);
47228 }
47229
47230 function createStore(storages, plugins, namespace) {
47231         if (!namespace) {
47232                 namespace = '';
47233         }
47234         if (storages && !isList(storages)) {
47235                 storages = [storages];
47236         }
47237         if (plugins && !isList(plugins)) {
47238                 plugins = [plugins];
47239         }
47240
47241         var namespacePrefix = (namespace ? '__storejs_'+namespace+'_' : '');
47242         var namespaceRegexp = (namespace ? new RegExp('^'+namespacePrefix) : null);
47243         var legalNamespaces = /^[a-zA-Z0-9_\-]*$/; // alpha-numeric + underscore and dash
47244         if (!legalNamespaces.test(namespace)) {
47245                 throw new Error('store.js namespaces can only have alphanumerics + underscores and dashes')
47246         }
47247         
47248         var _privateStoreProps = {
47249                 _namespacePrefix: namespacePrefix,
47250                 _namespaceRegexp: namespaceRegexp,
47251
47252                 _testStorage: function(storage) {
47253                         try {
47254                                 var testStr = '__storejs__test__';
47255                                 storage.write(testStr, testStr);
47256                                 var ok = (storage.read(testStr) === testStr);
47257                                 storage.remove(testStr);
47258                                 return ok
47259                         } catch(e) {
47260                                 return false
47261                         }
47262                 },
47263
47264                 _assignPluginFnProp: function(pluginFnProp, propName) {
47265                         var oldFn = this[propName];
47266                         this[propName] = function pluginFn() {
47267                                 var args = slice$7(arguments, 0);
47268                                 var self = this;
47269
47270                                 // super_fn calls the old function which was overwritten by
47271                                 // this mixin.
47272                                 function super_fn() {
47273                                         if (!oldFn) { return }
47274                                         each(arguments, function(arg, i) {
47275                                                 args[i] = arg;
47276                                         });
47277                                         return oldFn.apply(self, args)
47278                                 }
47279
47280                                 // Give mixing function access to super_fn by prefixing all mixin function
47281                                 // arguments with super_fn.
47282                                 var newFnArgs = [super_fn].concat(args);
47283
47284                                 return pluginFnProp.apply(self, newFnArgs)
47285                         };
47286                 },
47287
47288                 _serialize: function(obj) {
47289                         return JSON.stringify(obj)
47290                 },
47291
47292                 _deserialize: function(strVal, defaultVal) {
47293                         if (!strVal) { return defaultVal }
47294                         // It is possible that a raw string value has been previously stored
47295                         // in a storage without using store.js, meaning it will be a raw
47296                         // string value instead of a JSON serialized string. By defaulting
47297                         // to the raw string value in case of a JSON parse error, we allow
47298                         // for past stored values to be forwards-compatible with store.js
47299                         var val = '';
47300                         try { val = JSON.parse(strVal); }
47301                         catch(e) { val = strVal; }
47302
47303                         return (val !== undefined ? val : defaultVal)
47304                 },
47305                 
47306                 _addStorage: function(storage) {
47307                         if (this.enabled) { return }
47308                         if (this._testStorage(storage)) {
47309                                 this.storage = storage;
47310                                 this.enabled = true;
47311                         }
47312                 },
47313
47314                 _addPlugin: function(plugin) {
47315                         var self = this;
47316
47317                         // If the plugin is an array, then add all plugins in the array.
47318                         // This allows for a plugin to depend on other plugins.
47319                         if (isList(plugin)) {
47320                                 each(plugin, function(plugin) {
47321                                         self._addPlugin(plugin);
47322                                 });
47323                                 return
47324                         }
47325
47326                         // Keep track of all plugins we've seen so far, so that we
47327                         // don't add any of them twice.
47328                         var seenPlugin = pluck(this.plugins, function(seenPlugin) {
47329                                 return (plugin === seenPlugin)
47330                         });
47331                         if (seenPlugin) {
47332                                 return
47333                         }
47334                         this.plugins.push(plugin);
47335
47336                         // Check that the plugin is properly formed
47337                         if (!isFunction(plugin)) {
47338                                 throw new Error('Plugins must be function values that return objects')
47339                         }
47340
47341                         var pluginProperties = plugin.call(this);
47342                         if (!isObject(pluginProperties)) {
47343                                 throw new Error('Plugins must return an object of function properties')
47344                         }
47345
47346                         // Add the plugin function properties to this store instance.
47347                         each(pluginProperties, function(pluginFnProp, propName) {
47348                                 if (!isFunction(pluginFnProp)) {
47349                                         throw new Error('Bad plugin property: '+propName+' from plugin '+plugin.name+'. Plugins should only return functions.')
47350                                 }
47351                                 self._assignPluginFnProp(pluginFnProp, propName);
47352                         });
47353                 },
47354                 
47355                 // Put deprecated properties in the private API, so as to not expose it to accidential
47356                 // discovery through inspection of the store object.
47357                 
47358                 // Deprecated: addStorage
47359                 addStorage: function(storage) {
47360                         _warn('store.addStorage(storage) is deprecated. Use createStore([storages])');
47361                         this._addStorage(storage);
47362                 }
47363         };
47364
47365         var store = create$1(_privateStoreProps, storeAPI, {
47366                 plugins: []
47367         });
47368         store.raw = {};
47369         each(store, function(prop, propName) {
47370                 if (isFunction(prop)) {
47371                         store.raw[propName] = bind(store, prop);                        
47372                 }
47373         });
47374         each(storages, function(storage) {
47375                 store._addStorage(storage);
47376         });
47377         each(plugins, function(plugin) {
47378                 store._addPlugin(plugin);
47379         });
47380         return store
47381 }
47382
47383 var Global$1 = util.Global;
47384
47385 var localStorage_1 = {
47386         name: 'localStorage',
47387         read: read,
47388         write: write,
47389         each: each$2,
47390         remove: remove$2,
47391         clearAll: clearAll,
47392 };
47393
47394 function localStorage$1() {
47395         return Global$1.localStorage
47396 }
47397
47398 function read(key) {
47399         return localStorage$1().getItem(key)
47400 }
47401
47402 function write(key, data) {
47403         return localStorage$1().setItem(key, data)
47404 }
47405
47406 function each$2(fn) {
47407         for (var i = localStorage$1().length - 1; i >= 0; i--) {
47408                 var key = localStorage$1().key(i);
47409                 fn(read(key), key);
47410         }
47411 }
47412
47413 function remove$2(key) {
47414         return localStorage$1().removeItem(key)
47415 }
47416
47417 function clearAll() {
47418         return localStorage$1().clear()
47419 }
47420
47421 // oldFF-globalStorage provides storage for Firefox
47422 // versions 6 and 7, where no localStorage, etc
47423 // is available.
47424
47425
47426 var Global$2 = util.Global;
47427
47428 var oldFFGlobalStorage = {
47429         name: 'oldFF-globalStorage',
47430         read: read$1,
47431         write: write$1,
47432         each: each$3,
47433         remove: remove$3,
47434         clearAll: clearAll$1,
47435 };
47436
47437 var globalStorage = Global$2.globalStorage;
47438
47439 function read$1(key) {
47440         return globalStorage[key]
47441 }
47442
47443 function write$1(key, data) {
47444         globalStorage[key] = data;
47445 }
47446
47447 function each$3(fn) {
47448         for (var i = globalStorage.length - 1; i >= 0; i--) {
47449                 var key = globalStorage.key(i);
47450                 fn(globalStorage[key], key);
47451         }
47452 }
47453
47454 function remove$3(key) {
47455         return globalStorage.removeItem(key)
47456 }
47457
47458 function clearAll$1() {
47459         each$3(function(key, _) {
47460                 delete globalStorage[key];
47461         });
47462 }
47463
47464 // oldIE-userDataStorage provides storage for Internet Explorer
47465 // versions 6 and 7, where no localStorage, sessionStorage, etc
47466 // is available.
47467
47468
47469 var Global$3 = util.Global;
47470
47471 var oldIEUserDataStorage = {
47472         name: 'oldIE-userDataStorage',
47473         write: write$2,
47474         read: read$2,
47475         each: each$4,
47476         remove: remove$4,
47477         clearAll: clearAll$2,
47478 };
47479
47480 var storageName = 'storejs';
47481 var doc = Global$3.document;
47482 var _withStorageEl = _makeIEStorageElFunction();
47483 var disable = (Global$3.navigator ? Global$3.navigator.userAgent : '').match(/ (MSIE 8|MSIE 9|MSIE 10)\./); // MSIE 9.x, MSIE 10.x
47484
47485 function write$2(unfixedKey, data) {
47486         if (disable) { return }
47487         var fixedKey = fixKey(unfixedKey);
47488         _withStorageEl(function(storageEl) {
47489                 storageEl.setAttribute(fixedKey, data);
47490                 storageEl.save(storageName);
47491         });
47492 }
47493
47494 function read$2(unfixedKey) {
47495         if (disable) { return }
47496         var fixedKey = fixKey(unfixedKey);
47497         var res = null;
47498         _withStorageEl(function(storageEl) {
47499                 res = storageEl.getAttribute(fixedKey);
47500         });
47501         return res
47502 }
47503
47504 function each$4(callback) {
47505         _withStorageEl(function(storageEl) {
47506                 var attributes = storageEl.XMLDocument.documentElement.attributes;
47507                 for (var i=attributes.length-1; i>=0; i--) {
47508                         var attr = attributes[i];
47509                         callback(storageEl.getAttribute(attr.name), attr.name);
47510                 }
47511         });
47512 }
47513
47514 function remove$4(unfixedKey) {
47515         var fixedKey = fixKey(unfixedKey);
47516         _withStorageEl(function(storageEl) {
47517                 storageEl.removeAttribute(fixedKey);
47518                 storageEl.save(storageName);
47519         });
47520 }
47521
47522 function clearAll$2() {
47523         _withStorageEl(function(storageEl) {
47524                 var attributes = storageEl.XMLDocument.documentElement.attributes;
47525                 storageEl.load(storageName);
47526                 for (var i=attributes.length-1; i>=0; i--) {
47527                         storageEl.removeAttribute(attributes[i].name);
47528                 }
47529                 storageEl.save(storageName);
47530         });
47531 }
47532
47533 // Helpers
47534 //////////
47535
47536 // In IE7, keys cannot start with a digit or contain certain chars.
47537 // See https://github.com/marcuswestin/store.js/issues/40
47538 // See https://github.com/marcuswestin/store.js/issues/83
47539 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
47540 function fixKey(key) {
47541         return key.replace(/^\d/, '___$&').replace(forbiddenCharsRegex, '___')
47542 }
47543
47544 function _makeIEStorageElFunction() {
47545         if (!doc || !doc.documentElement || !doc.documentElement.addBehavior) {
47546                 return null
47547         }
47548         var scriptTag = 'script',
47549                 storageOwner,
47550                 storageContainer,
47551                 storageEl;
47552
47553         // Since #userData storage applies only to specific paths, we need to
47554         // somehow link our data to a specific path.  We choose /favicon.ico
47555         // as a pretty safe option, since all browsers already make a request to
47556         // this URL anyway and being a 404 will not hurt us here.  We wrap an
47557         // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
47558         // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
47559         // since the iframe access rules appear to allow direct access and
47560         // manipulation of the document element, even for a 404 page.  This
47561         // document can be used instead of the current document (which would
47562         // have been limited to the current path) to perform #userData storage.
47563         try {
47564                 /* global ActiveXObject */
47565                 storageContainer = new ActiveXObject('htmlfile');
47566                 storageContainer.open();
47567                 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
47568                 storageContainer.close();
47569                 storageOwner = storageContainer.w.frames[0].document;
47570                 storageEl = storageOwner.createElement('div');
47571         } catch(e) {
47572                 // somehow ActiveXObject instantiation failed (perhaps some special
47573                 // security settings or otherwse), fall back to per-path storage
47574                 storageEl = doc.createElement('div');
47575                 storageOwner = doc.body;
47576         }
47577
47578         return function(storeFunction) {
47579                 var args = [].slice.call(arguments, 0);
47580                 args.unshift(storageEl);
47581                 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
47582                 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
47583                 storageOwner.appendChild(storageEl);
47584                 storageEl.addBehavior('#default#userData');
47585                 storageEl.load(storageName);
47586                 storeFunction.apply(this, args);
47587                 storageOwner.removeChild(storageEl);
47588                 return
47589         }
47590 }
47591
47592 // cookieStorage is useful Safari private browser mode, where localStorage
47593 // doesn't work but cookies do. This implementation is adopted from
47594 // https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage
47595
47596
47597 var Global$4 = util.Global;
47598 var trim$1 = util.trim;
47599
47600 var cookieStorage = {
47601         name: 'cookieStorage',
47602         read: read$3,
47603         write: write$3,
47604         each: each$5,
47605         remove: remove$5,
47606         clearAll: clearAll$3,
47607 };
47608
47609 var doc$1 = Global$4.document;
47610
47611 function read$3(key) {
47612         if (!key || !_has(key)) { return null }
47613         var regexpStr = "(?:^|.*;\\s*)" +
47614                 escape(key).replace(/[\-\.\+\*]/g, "\\$&") +
47615                 "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";
47616         return unescape(doc$1.cookie.replace(new RegExp(regexpStr), "$1"))
47617 }
47618
47619 function each$5(callback) {
47620         var cookies = doc$1.cookie.split(/; ?/g);
47621         for (var i = cookies.length - 1; i >= 0; i--) {
47622                 if (!trim$1(cookies[i])) {
47623                         continue
47624                 }
47625                 var kvp = cookies[i].split('=');
47626                 var key = unescape(kvp[0]);
47627                 var val = unescape(kvp[1]);
47628                 callback(val, key);
47629         }
47630 }
47631
47632 function write$3(key, data) {
47633         if(!key) { return }
47634         doc$1.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
47635 }
47636
47637 function remove$5(key) {
47638         if (!key || !_has(key)) {
47639                 return
47640         }
47641         doc$1.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
47642 }
47643
47644 function clearAll$3() {
47645         each$5(function(_, key) {
47646                 remove$5(key);
47647         });
47648 }
47649
47650 function _has(key) {
47651         return (new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(doc$1.cookie)
47652 }
47653
47654 var Global$5 = util.Global;
47655
47656 var sessionStorage_1 = {
47657         name: 'sessionStorage',
47658         read: read$4,
47659         write: write$4,
47660         each: each$6,
47661         remove: remove$6,
47662         clearAll: clearAll$4
47663 };
47664
47665 function sessionStorage() {
47666         return Global$5.sessionStorage
47667 }
47668
47669 function read$4(key) {
47670         return sessionStorage().getItem(key)
47671 }
47672
47673 function write$4(key, data) {
47674         return sessionStorage().setItem(key, data)
47675 }
47676
47677 function each$6(fn) {
47678         for (var i = sessionStorage().length - 1; i >= 0; i--) {
47679                 var key = sessionStorage().key(i);
47680                 fn(read$4(key), key);
47681         }
47682 }
47683
47684 function remove$6(key) {
47685         return sessionStorage().removeItem(key)
47686 }
47687
47688 function clearAll$4() {
47689         return sessionStorage().clear()
47690 }
47691
47692 // memoryStorage is a useful last fallback to ensure that the store
47693 // is functions (meaning store.get(), store.set(), etc will all function).
47694 // However, stored values will not persist when the browser navigates to
47695 // a new page or reloads the current page.
47696
47697 var memoryStorage_1 = {
47698         name: 'memoryStorage',
47699         read: read$5,
47700         write: write$5,
47701         each: each$7,
47702         remove: remove$7,
47703         clearAll: clearAll$5,
47704 };
47705
47706 var memoryStorage = {};
47707
47708 function read$5(key) {
47709         return memoryStorage[key]
47710 }
47711
47712 function write$5(key, data) {
47713         memoryStorage[key] = data;
47714 }
47715
47716 function each$7(callback) {
47717         for (var key in memoryStorage) {
47718                 if (memoryStorage.hasOwnProperty(key)) {
47719                         callback(memoryStorage[key], key);
47720                 }
47721         }
47722 }
47723
47724 function remove$7(key) {
47725         delete memoryStorage[key];
47726 }
47727
47728 function clearAll$5(key) {
47729         memoryStorage = {};
47730 }
47731
47732 var all$3 = [
47733         // Listed in order of usage preference
47734         localStorage_1,
47735         oldFFGlobalStorage,
47736         oldIEUserDataStorage,
47737         cookieStorage,
47738         sessionStorage_1,
47739         memoryStorage_1
47740 ];
47741
47742 /* eslint-disable */
47743
47744 //  json2.js
47745 //  2016-10-28
47746 //  Public Domain.
47747 //  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
47748 //  See http://www.JSON.org/js.html
47749 //  This code should be minified before deployment.
47750 //  See http://javascript.crockford.com/jsmin.html
47751
47752 //  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
47753 //  NOT CONTROL.
47754
47755 //  This file creates a global JSON object containing two methods: stringify
47756 //  and parse. This file provides the ES5 JSON capability to ES3 systems.
47757 //  If a project might run on IE8 or earlier, then this file should be included.
47758 //  This file does nothing on ES5 systems.
47759
47760 //      JSON.stringify(value, replacer, space)
47761 //          value       any JavaScript value, usually an object or array.
47762 //          replacer    an optional parameter that determines how object
47763 //                      values are stringified for objects. It can be a
47764 //                      function or an array of strings.
47765 //          space       an optional parameter that specifies the indentation
47766 //                      of nested structures. If it is omitted, the text will
47767 //                      be packed without extra whitespace. If it is a number,
47768 //                      it will specify the number of spaces to indent at each
47769 //                      level. If it is a string (such as "\t" or "&nbsp;"),
47770 //                      it contains the characters used to indent at each level.
47771 //          This method produces a JSON text from a JavaScript value.
47772 //          When an object value is found, if the object contains a toJSON
47773 //          method, its toJSON method will be called and the result will be
47774 //          stringified. A toJSON method does not serialize: it returns the
47775 //          value represented by the name/value pair that should be serialized,
47776 //          or undefined if nothing should be serialized. The toJSON method
47777 //          will be passed the key associated with the value, and this will be
47778 //          bound to the value.
47779
47780 //          For example, this would serialize Dates as ISO strings.
47781
47782 //              Date.prototype.toJSON = function (key) {
47783 //                  function f(n) {
47784 //                      // Format integers to have at least two digits.
47785 //                      return (n < 10)
47786 //                          ? "0" + n
47787 //                          : n;
47788 //                  }
47789 //                  return this.getUTCFullYear()   + "-" +
47790 //                       f(this.getUTCMonth() + 1) + "-" +
47791 //                       f(this.getUTCDate())      + "T" +
47792 //                       f(this.getUTCHours())     + ":" +
47793 //                       f(this.getUTCMinutes())   + ":" +
47794 //                       f(this.getUTCSeconds())   + "Z";
47795 //              };
47796
47797 //          You can provide an optional replacer method. It will be passed the
47798 //          key and value of each member, with this bound to the containing
47799 //          object. The value that is returned from your method will be
47800 //          serialized. If your method returns undefined, then the member will
47801 //          be excluded from the serialization.
47802
47803 //          If the replacer parameter is an array of strings, then it will be
47804 //          used to select the members to be serialized. It filters the results
47805 //          such that only members with keys listed in the replacer array are
47806 //          stringified.
47807
47808 //          Values that do not have JSON representations, such as undefined or
47809 //          functions, will not be serialized. Such values in objects will be
47810 //          dropped; in arrays they will be replaced with null. You can use
47811 //          a replacer function to replace those with JSON values.
47812
47813 //          JSON.stringify(undefined) returns undefined.
47814
47815 //          The optional space parameter produces a stringification of the
47816 //          value that is filled with line breaks and indentation to make it
47817 //          easier to read.
47818
47819 //          If the space parameter is a non-empty string, then that string will
47820 //          be used for indentation. If the space parameter is a number, then
47821 //          the indentation will be that many spaces.
47822
47823 //          Example:
47824
47825 //          text = JSON.stringify(["e", {pluribus: "unum"}]);
47826 //          // text is '["e",{"pluribus":"unum"}]'
47827
47828 //          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
47829 //          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
47830
47831 //          text = JSON.stringify([new Date()], function (key, value) {
47832 //              return this[key] instanceof Date
47833 //                  ? "Date(" + this[key] + ")"
47834 //                  : value;
47835 //          });
47836 //          // text is '["Date(---current time---)"]'
47837
47838 //      JSON.parse(text, reviver)
47839 //          This method parses a JSON text to produce an object or array.
47840 //          It can throw a SyntaxError exception.
47841
47842 //          The optional reviver parameter is a function that can filter and
47843 //          transform the results. It receives each of the keys and values,
47844 //          and its return value is used instead of the original value.
47845 //          If it returns what it received, then the structure is not modified.
47846 //          If it returns undefined then the member is deleted.
47847
47848 //          Example:
47849
47850 //          // Parse the text. Values that look like ISO date strings will
47851 //          // be converted to Date objects.
47852
47853 //          myData = JSON.parse(text, function (key, value) {
47854 //              var a;
47855 //              if (typeof value === "string") {
47856 //                  a =
47857 //   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
47858 //                  if (a) {
47859 //                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
47860 //                          +a[5], +a[6]));
47861 //                  }
47862 //              }
47863 //              return value;
47864 //          });
47865
47866 //          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
47867 //              var d;
47868 //              if (typeof value === "string" &&
47869 //                      value.slice(0, 5) === "Date(" &&
47870 //                      value.slice(-1) === ")") {
47871 //                  d = new Date(value.slice(5, -1));
47872 //                  if (d) {
47873 //                      return d;
47874 //                  }
47875 //              }
47876 //              return value;
47877 //          });
47878
47879 //  This is a reference implementation. You are free to copy, modify, or
47880 //  redistribute.
47881
47882 /*jslint
47883     eval, for, this
47884 */
47885
47886 /*property
47887     JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
47888     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
47889     lastIndex, length, parse, prototype, push, replace, slice, stringify,
47890     test, toJSON, toString, valueOf
47891 */
47892
47893
47894 // Create a JSON object only if one does not already exist. We create the
47895 // methods in a closure to avoid creating global variables.
47896
47897 if (typeof JSON !== "object") {
47898     JSON = {};
47899 }
47900
47901 (function () {
47902     "use strict";
47903
47904     var rx_one = /^[\],:{}\s]*$/;
47905     var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
47906     var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
47907     var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
47908     var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
47909     var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
47910
47911     function f(n) {
47912         // Format integers to have at least two digits.
47913         return n < 10
47914             ? "0" + n
47915             : n;
47916     }
47917
47918     function this_value() {
47919         return this.valueOf();
47920     }
47921
47922     if (typeof Date.prototype.toJSON !== "function") {
47923
47924         Date.prototype.toJSON = function () {
47925
47926             return isFinite(this.valueOf())
47927                 ? this.getUTCFullYear() + "-" +
47928                         f(this.getUTCMonth() + 1) + "-" +
47929                         f(this.getUTCDate()) + "T" +
47930                         f(this.getUTCHours()) + ":" +
47931                         f(this.getUTCMinutes()) + ":" +
47932                         f(this.getUTCSeconds()) + "Z"
47933                 : null;
47934         };
47935
47936         Boolean.prototype.toJSON = this_value;
47937         Number.prototype.toJSON = this_value;
47938         String.prototype.toJSON = this_value;
47939     }
47940
47941     var gap;
47942     var indent;
47943     var meta;
47944     var rep;
47945
47946
47947     function quote(string) {
47948
47949 // If the string contains no control characters, no quote characters, and no
47950 // backslash characters, then we can safely slap some quotes around it.
47951 // Otherwise we must also replace the offending characters with safe escape
47952 // sequences.
47953
47954         rx_escapable.lastIndex = 0;
47955         return rx_escapable.test(string)
47956             ? "\"" + string.replace(rx_escapable, function (a) {
47957                 var c = meta[a];
47958                 return typeof c === "string"
47959                     ? c
47960                     : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
47961             }) + "\""
47962             : "\"" + string + "\"";
47963     }
47964
47965
47966     function str(key, holder) {
47967
47968 // Produce a string from holder[key].
47969
47970         var i;          // The loop counter.
47971         var k;          // The member key.
47972         var v;          // The member value.
47973         var length;
47974         var mind = gap;
47975         var partial;
47976         var value = holder[key];
47977
47978 // If the value has a toJSON method, call it to obtain a replacement value.
47979
47980         if (value && typeof value === "object" &&
47981                 typeof value.toJSON === "function") {
47982             value = value.toJSON(key);
47983         }
47984
47985 // If we were called with a replacer function, then call the replacer to
47986 // obtain a replacement value.
47987
47988         if (typeof rep === "function") {
47989             value = rep.call(holder, key, value);
47990         }
47991
47992 // What happens next depends on the value's type.
47993
47994         switch (typeof value) {
47995         case "string":
47996             return quote(value);
47997
47998         case "number":
47999
48000 // JSON numbers must be finite. Encode non-finite numbers as null.
48001
48002             return isFinite(value)
48003                 ? String(value)
48004                 : "null";
48005
48006         case "boolean":
48007         case "null":
48008
48009 // If the value is a boolean or null, convert it to a string. Note:
48010 // typeof null does not produce "null". The case is included here in
48011 // the remote chance that this gets fixed someday.
48012
48013             return String(value);
48014
48015 // If the type is "object", we might be dealing with an object or an array or
48016 // null.
48017
48018         case "object":
48019
48020 // Due to a specification blunder in ECMAScript, typeof null is "object",
48021 // so watch out for that case.
48022
48023             if (!value) {
48024                 return "null";
48025             }
48026
48027 // Make an array to hold the partial results of stringifying this object value.
48028
48029             gap += indent;
48030             partial = [];
48031
48032 // Is the value an array?
48033
48034             if (Object.prototype.toString.apply(value) === "[object Array]") {
48035
48036 // The value is an array. Stringify every element. Use null as a placeholder
48037 // for non-JSON values.
48038
48039                 length = value.length;
48040                 for (i = 0; i < length; i += 1) {
48041                     partial[i] = str(i, value) || "null";
48042                 }
48043
48044 // Join all of the elements together, separated with commas, and wrap them in
48045 // brackets.
48046
48047                 v = partial.length === 0
48048                     ? "[]"
48049                     : gap
48050                         ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
48051                         : "[" + partial.join(",") + "]";
48052                 gap = mind;
48053                 return v;
48054             }
48055
48056 // If the replacer is an array, use it to select the members to be stringified.
48057
48058             if (rep && typeof rep === "object") {
48059                 length = rep.length;
48060                 for (i = 0; i < length; i += 1) {
48061                     if (typeof rep[i] === "string") {
48062                         k = rep[i];
48063                         v = str(k, value);
48064                         if (v) {
48065                             partial.push(quote(k) + (
48066                                 gap
48067                                     ? ": "
48068                                     : ":"
48069                             ) + v);
48070                         }
48071                     }
48072                 }
48073             } else {
48074
48075 // Otherwise, iterate through all of the keys in the object.
48076
48077                 for (k in value) {
48078                     if (Object.prototype.hasOwnProperty.call(value, k)) {
48079                         v = str(k, value);
48080                         if (v) {
48081                             partial.push(quote(k) + (
48082                                 gap
48083                                     ? ": "
48084                                     : ":"
48085                             ) + v);
48086                         }
48087                     }
48088                 }
48089             }
48090
48091 // Join all of the member texts together, separated with commas,
48092 // and wrap them in braces.
48093
48094             v = partial.length === 0
48095                 ? "{}"
48096                 : gap
48097                     ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
48098                     : "{" + partial.join(",") + "}";
48099             gap = mind;
48100             return v;
48101         }
48102     }
48103
48104 // If the JSON object does not yet have a stringify method, give it one.
48105
48106     if (typeof JSON.stringify !== "function") {
48107         meta = {    // table of character substitutions
48108             "\b": "\\b",
48109             "\t": "\\t",
48110             "\n": "\\n",
48111             "\f": "\\f",
48112             "\r": "\\r",
48113             "\"": "\\\"",
48114             "\\": "\\\\"
48115         };
48116         JSON.stringify = function (value, replacer, space) {
48117
48118 // The stringify method takes a value and an optional replacer, and an optional
48119 // space parameter, and returns a JSON text. The replacer can be a function
48120 // that can replace values, or an array of strings that will select the keys.
48121 // A default replacer method can be provided. Use of the space parameter can
48122 // produce text that is more easily readable.
48123
48124             var i;
48125             gap = "";
48126             indent = "";
48127
48128 // If the space parameter is a number, make an indent string containing that
48129 // many spaces.
48130
48131             if (typeof space === "number") {
48132                 for (i = 0; i < space; i += 1) {
48133                     indent += " ";
48134                 }
48135
48136 // If the space parameter is a string, it will be used as the indent string.
48137
48138             } else if (typeof space === "string") {
48139                 indent = space;
48140             }
48141
48142 // If there is a replacer, it must be a function or an array.
48143 // Otherwise, throw an error.
48144
48145             rep = replacer;
48146             if (replacer && typeof replacer !== "function" &&
48147                     (typeof replacer !== "object" ||
48148                     typeof replacer.length !== "number")) {
48149                 throw new Error("JSON.stringify");
48150             }
48151
48152 // Make a fake root object containing our value under the key of "".
48153 // Return the result of stringifying the value.
48154
48155             return str("", {"": value});
48156         };
48157     }
48158
48159
48160 // If the JSON object does not yet have a parse method, give it one.
48161
48162     if (typeof JSON.parse !== "function") {
48163         JSON.parse = function (text, reviver) {
48164
48165 // The parse method takes a text and an optional reviver function, and returns
48166 // a JavaScript value if the text is a valid JSON text.
48167
48168             var j;
48169
48170             function walk(holder, key) {
48171
48172 // The walk method is used to recursively walk the resulting structure so
48173 // that modifications can be made.
48174
48175                 var k;
48176                 var v;
48177                 var value = holder[key];
48178                 if (value && typeof value === "object") {
48179                     for (k in value) {
48180                         if (Object.prototype.hasOwnProperty.call(value, k)) {
48181                             v = walk(value, k);
48182                             if (v !== undefined) {
48183                                 value[k] = v;
48184                             } else {
48185                                 delete value[k];
48186                             }
48187                         }
48188                     }
48189                 }
48190                 return reviver.call(holder, key, value);
48191             }
48192
48193
48194 // Parsing happens in four stages. In the first stage, we replace certain
48195 // Unicode characters with escape sequences. JavaScript handles many characters
48196 // incorrectly, either silently deleting them, or treating them as line endings.
48197
48198             text = String(text);
48199             rx_dangerous.lastIndex = 0;
48200             if (rx_dangerous.test(text)) {
48201                 text = text.replace(rx_dangerous, function (a) {
48202                     return "\\u" +
48203                             ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
48204                 });
48205             }
48206
48207 // In the second stage, we run the text against regular expressions that look
48208 // for non-JSON patterns. We are especially concerned with "()" and "new"
48209 // because they can cause invocation, and "=" because it can cause mutation.
48210 // But just to be safe, we want to reject all unexpected forms.
48211
48212 // We split the second stage into 4 regexp operations in order to work around
48213 // crippling inefficiencies in IE's and Safari's regexp engines. First we
48214 // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
48215 // replace all simple value tokens with "]" characters. Third, we delete all
48216 // open brackets that follow a colon or comma or that begin the text. Finally,
48217 // we look to see that the remaining characters are only whitespace or "]" or
48218 // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
48219
48220             if (
48221                 rx_one.test(
48222                     text
48223                         .replace(rx_two, "@")
48224                         .replace(rx_three, "]")
48225                         .replace(rx_four, "")
48226                 )
48227             ) {
48228
48229 // In the third stage we use the eval function to compile the text into a
48230 // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
48231 // in JavaScript: it can begin a block or an object literal. We wrap the text
48232 // in parens to eliminate the ambiguity.
48233
48234                 j = eval("(" + text + ")");
48235
48236 // In the optional fourth stage, we recursively walk the new structure, passing
48237 // each name/value pair to a reviver function for possible transformation.
48238
48239                 return (typeof reviver === "function")
48240                     ? walk({"": j}, "")
48241                     : j;
48242             }
48243
48244 // If the text is not JSON parseable, then a SyntaxError is thrown.
48245
48246             throw new SyntaxError("JSON.parse");
48247         };
48248     }
48249 }());
48250
48251 var json2 = json2Plugin;
48252
48253 function json2Plugin() {
48254         
48255         return {}
48256 }
48257
48258 var plugins = [json2];
48259
48260 var store_legacy = storeEngine.createStore(all$3, plugins);
48261
48262 // # osm-auth
48263 //
48264 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
48265 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
48266 // does not support custom headers, which this uses everywhere.
48267 var index$12 = function(o) {
48268
48269     var oauth = {};
48270
48271     // authenticated users will also have a request token secret, but it's
48272     // not used in transactions with the server
48273     oauth.authenticated = function() {
48274         return !!(token('oauth_token') && token('oauth_token_secret'));
48275     };
48276
48277     oauth.logout = function() {
48278         token('oauth_token', '');
48279         token('oauth_token_secret', '');
48280         token('oauth_request_token_secret', '');
48281         return oauth;
48282     };
48283
48284     // TODO: detect lack of click event
48285     oauth.authenticate = function(callback) {
48286         if (oauth.authenticated()) return callback();
48287
48288         oauth.logout();
48289
48290         // ## Getting a request token
48291         var params = timenonce(getAuth(o)),
48292             url = o.url + '/oauth/request_token';
48293
48294         params.oauth_signature = index$13.signature(
48295             o.oauth_secret, '',
48296             index$13.baseString('POST', url, params));
48297
48298         if (!o.singlepage) {
48299             // Create a 600x550 popup window in the center of the screen
48300             var w = 600, h = 550,
48301                 settings = [
48302                     ['width', w], ['height', h],
48303                     ['left', screen.width / 2 - w / 2],
48304                     ['top', screen.height / 2 - h / 2]].map(function(x) {
48305                         return x.join('=');
48306                     }).join(','),
48307                 popup = window.open('about:blank', 'oauth_window', settings);
48308         }
48309
48310         // Request a request token. When this is complete, the popup
48311         // window is redirected to OSM's authorization page.
48312         index$13.xhr('POST', url, params, null, {}, reqTokenDone);
48313         o.loading();
48314
48315         function reqTokenDone(err, xhr) {
48316             o.done();
48317             if (err) return callback(err);
48318             var resp = index$13.stringQs(xhr.response);
48319             token('oauth_request_token_secret', resp.oauth_token_secret);
48320             var authorize_url = o.url + '/oauth/authorize?' + index$13.qsString({
48321                 oauth_token: resp.oauth_token,
48322                 oauth_callback: resolveUrl(o.landing)
48323             });
48324
48325             if (o.singlepage) {
48326                 location.href = authorize_url;
48327             } else {
48328                 popup.location = authorize_url;
48329             }
48330         }
48331
48332         // Called by a function in a landing page, in the popup window. The
48333         // window closes itself.
48334         window.authComplete = function(token) {
48335             var oauth_token = index$13.stringQs(token.split('?')[1]);
48336             get_access_token(oauth_token.oauth_token);
48337             delete window.authComplete;
48338         };
48339
48340         // ## Getting an request token
48341         //
48342         // At this point we have an `oauth_token`, brought in from a function
48343         // call on a landing page popup.
48344         function get_access_token(oauth_token) {
48345             var url = o.url + '/oauth/access_token',
48346                 params = timenonce(getAuth(o)),
48347                 request_token_secret = token('oauth_request_token_secret');
48348             params.oauth_token = oauth_token;
48349             params.oauth_signature = index$13.signature(
48350                 o.oauth_secret,
48351                 request_token_secret,
48352                 index$13.baseString('POST', url, params));
48353
48354             // ## Getting an access token
48355             //
48356             // The final token required for authentication. At this point
48357             // we have a `request token secret`
48358             index$13.xhr('POST', url, params, null, {}, accessTokenDone);
48359             o.loading();
48360         }
48361
48362         function accessTokenDone(err, xhr) {
48363             o.done();
48364             if (err) return callback(err);
48365             var access_token = index$13.stringQs(xhr.response);
48366             token('oauth_token', access_token.oauth_token);
48367             token('oauth_token_secret', access_token.oauth_token_secret);
48368             callback(null, oauth);
48369         }
48370     };
48371
48372     oauth.bootstrapToken = function(oauth_token, callback) {
48373         // ## Getting an request token
48374         // At this point we have an `oauth_token`, brought in from a function
48375         // call on a landing page popup.
48376         function get_access_token(oauth_token) {
48377             var url = o.url + '/oauth/access_token',
48378                 params = timenonce(getAuth(o)),
48379                 request_token_secret = token('oauth_request_token_secret');
48380             params.oauth_token = oauth_token;
48381             params.oauth_signature = index$13.signature(
48382                 o.oauth_secret,
48383                 request_token_secret,
48384                 index$13.baseString('POST', url, params));
48385
48386             // ## Getting an access token
48387             // The final token required for authentication. At this point
48388             // we have a `request token secret`
48389             index$13.xhr('POST', url, params, null, {}, accessTokenDone);
48390             o.loading();
48391         }
48392
48393         function accessTokenDone(err, xhr) {
48394             o.done();
48395             if (err) return callback(err);
48396             var access_token = index$13.stringQs(xhr.response);
48397             token('oauth_token', access_token.oauth_token);
48398             token('oauth_token_secret', access_token.oauth_token_secret);
48399             callback(null, oauth);
48400         }
48401
48402         get_access_token(oauth_token);
48403     };
48404
48405     // # xhr
48406     //
48407     // A single XMLHttpRequest wrapper that does authenticated calls if the
48408     // user has logged in.
48409     oauth.xhr = function(options, callback) {
48410         if (!oauth.authenticated()) {
48411             if (o.auto) {
48412                 return oauth.authenticate(run);
48413             } else {
48414                 callback('not authenticated', null);
48415                 return;
48416             }
48417         } else {
48418             return run();
48419         }
48420
48421         function run() {
48422             var params = timenonce(getAuth(o)),
48423                 oauth_token_secret = token('oauth_token_secret'),
48424                 url = (options.prefix !== false) ? o.url + options.path : options.path,
48425                 url_parts = url.replace(/#.*$/, '').split('?', 2),
48426                 base_url = url_parts[0],
48427                 query = (url_parts.length === 2) ? url_parts[1] : '';
48428
48429             // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
48430             if ((!options.options || !options.options.header ||
48431                 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
48432                 options.content) {
48433                 params = immutable(params, index$13.stringQs(options.content));
48434             }
48435
48436             params.oauth_token = token('oauth_token');
48437             params.oauth_signature = index$13.signature(
48438                 o.oauth_secret,
48439                 oauth_token_secret,
48440                 index$13.baseString(options.method, base_url, immutable(params, index$13.stringQs(query)))
48441             );
48442
48443             return index$13.xhr(options.method, url, params, options.content, options.options, done);
48444         }
48445
48446         function done(err, xhr) {
48447             if (err) return callback(err);
48448             else if (xhr.responseXML) return callback(err, xhr.responseXML);
48449             else return callback(err, xhr.response);
48450         }
48451     };
48452
48453     // pre-authorize this object, if we can just get a token and token_secret
48454     // from the start
48455     oauth.preauth = function(c) {
48456         if (!c) return;
48457         if (c.oauth_token) token('oauth_token', c.oauth_token);
48458         if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
48459         return oauth;
48460     };
48461
48462     oauth.options = function(_) {
48463         if (!arguments.length) return o;
48464
48465         o = _;
48466         o.url = o.url || 'https://www.openstreetmap.org';
48467         o.landing = o.landing || 'land.html';
48468         o.singlepage = o.singlepage || false;
48469
48470         // Optional loading and loading-done functions for nice UI feedback.
48471         // by default, no-ops
48472         o.loading = o.loading || function() {};
48473         o.done = o.done || function() {};
48474
48475         return oauth.preauth(o);
48476     };
48477
48478     // 'stamp' an authentication object from `getAuth()`
48479     // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
48480     // and timestamp
48481     function timenonce(o) {
48482         o.oauth_timestamp = index$13.timestamp();
48483         o.oauth_nonce = index$13.nonce();
48484         return o;
48485     }
48486
48487     // get/set tokens. These are prefixed with the base URL so that `osm-auth`
48488     // can be used with multiple APIs and the keys in `localStorage`
48489     // will not clash
48490     var token;
48491
48492     if (store_legacy.enabled) {
48493         token = function (x, y) {
48494             if (arguments.length === 1) return store_legacy.get(o.url + x);
48495             else if (arguments.length === 2) return store_legacy.set(o.url + x, y);
48496         };
48497     } else {
48498         var storage = {};
48499         token = function (x, y) {
48500             if (arguments.length === 1) return storage[o.url + x];
48501             else if (arguments.length === 2) return storage[o.url + x] = y;
48502         };
48503     }
48504
48505     // Get an authentication object. If you just add and remove properties
48506     // from a single object, you'll need to use `delete` to make sure that
48507     // it doesn't contain undesired properties for authentication
48508     function getAuth(o) {
48509         return {
48510             oauth_consumer_key: o.oauth_consumer_key,
48511             oauth_signature_method: 'HMAC-SHA1'
48512         };
48513     }
48514
48515     // potentially pre-authorize
48516     oauth.options(o);
48517
48518     return oauth;
48519 };
48520
48521 var JXON = new (function () {
48522   var
48523     sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
48524     aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
48525
48526   function parseText (sValue) {
48527     if (rIsNull.test(sValue)) { return null; }
48528     if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
48529     if (isFinite(sValue)) { return parseFloat(sValue); }
48530     if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
48531     return sValue;
48532   }
48533
48534   function EmptyTree () { }
48535   EmptyTree.prototype.toString = function () { return 'null'; };
48536   EmptyTree.prototype.valueOf = function () { return null; };
48537
48538   function objectify (vValue) {
48539     return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
48540   }
48541
48542   function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
48543     var
48544       nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
48545       bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
48546
48547     var
48548       sProp, vContent, nLength = 0, sCollectedTxt = '',
48549       vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
48550
48551     if (bChildren) {
48552       for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
48553         oNode = oParentNode.childNodes.item(nItem);
48554         if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
48555         else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
48556         else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
48557       }
48558     }
48559
48560     var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
48561
48562     if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
48563
48564     for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
48565       sProp = aCache[nElId].nodeName.toLowerCase();
48566       vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
48567       if (vResult.hasOwnProperty(sProp)) {
48568         if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
48569         vResult[sProp].push(vContent);
48570       } else {
48571         vResult[sProp] = vContent;
48572         nLength++;
48573       }
48574     }
48575
48576     if (bAttributes) {
48577       var
48578         nAttrLen = oParentNode.attributes.length,
48579         sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
48580
48581       for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
48582         oAttrib = oParentNode.attributes.item(nAttrib);
48583         oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
48584       }
48585
48586       if (bNesteAttr) {
48587         if (bFreeze) { Object.freeze(oAttrParent); }
48588         vResult[sAttributesProp] = oAttrParent;
48589         nLength -= nAttrLen - 1;
48590       }
48591     }
48592
48593     if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
48594       vResult[sValueProp] = vBuiltVal;
48595     } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
48596       vResult = vBuiltVal;
48597     }
48598
48599     if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
48600
48601     aCache.length = nLevelStart;
48602
48603     return vResult;
48604   }
48605
48606   function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
48607     var vValue, oChild;
48608
48609     if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
48610       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
48611     } else if (oParentObj.constructor === Date) {
48612       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));    
48613     }
48614
48615     for (var sName in oParentObj) {
48616       vValue = oParentObj[sName];
48617       if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
48618       if (sName === sValueProp) {
48619         if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
48620       } else if (sName === sAttributesProp) { /* verbosity level is 3 */
48621         for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
48622       } else if (sName.charAt(0) === sAttrPref) {
48623         oParentEl.setAttribute(sName.slice(1), vValue);
48624       } else if (vValue.constructor === Array) {
48625         for (var nItem = 0; nItem < vValue.length; nItem++) {
48626           oChild = oXMLDoc.createElement(sName);
48627           loadObjTree(oXMLDoc, oChild, vValue[nItem]);
48628           oParentEl.appendChild(oChild);
48629         }
48630       } else {
48631         oChild = oXMLDoc.createElement(sName);
48632         if (vValue instanceof Object) {
48633           loadObjTree(oXMLDoc, oChild, vValue);
48634         } else if (vValue !== null && vValue !== true) {
48635           oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
48636         }
48637         oParentEl.appendChild(oChild);
48638      }
48639    }
48640   }
48641
48642   this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
48643     var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
48644     return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);    
48645   };
48646
48647   this.unbuild = function (oObjTree) {    
48648     var oNewDoc = document.implementation.createDocument('', '', null);
48649     loadObjTree(oNewDoc, oNewDoc, oObjTree);
48650     return oNewDoc;
48651   };
48652
48653   this.stringify = function (oObjTree) {
48654     return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
48655   };
48656 })();
48657
48658 // var myObject = JXON.build(doc);
48659 // we got our javascript object! try: alert(JSON.stringify(myObject));
48660
48661 // var newDoc = JXON.unbuild(myObject);
48662 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
48663
48664 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
48665 var urlroot = 'https://www.openstreetmap.org';
48666 var blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
48667 var inflight$1 = {};
48668 var loadedTiles = {};
48669 var entityCache = {};
48670 var tileZoom$1 = 16;
48671 var oauth = index$12({
48672         url: urlroot,
48673         oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
48674         oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
48675         loading: authLoading,
48676         done: authDone
48677     });
48678 var rateLimitError;
48679 var userChangesets;
48680 var userDetails;
48681 var off;
48682
48683
48684 function authLoading() {
48685     dispatch$3.call('authLoading');
48686 }
48687
48688
48689 function authDone() {
48690     dispatch$3.call('authDone');
48691 }
48692
48693
48694 function abortRequest$1(i) {
48695     if (i) {
48696         i.abort();
48697     }
48698 }
48699
48700
48701 function getLoc(attrs) {
48702     var lon = attrs.lon && attrs.lon.value,
48703         lat = attrs.lat && attrs.lat.value;
48704     return [parseFloat(lon), parseFloat(lat)];
48705 }
48706
48707
48708 function getNodes(obj) {
48709     var elems = obj.getElementsByTagName('nd'),
48710         nodes = new Array(elems.length);
48711     for (var i = 0, l = elems.length; i < l; i++) {
48712         nodes[i] = 'n' + elems[i].attributes.ref.value;
48713     }
48714     return nodes;
48715 }
48716
48717
48718 function getTags(obj) {
48719     var elems = obj.getElementsByTagName('tag'),
48720         tags = {};
48721     for (var i = 0, l = elems.length; i < l; i++) {
48722         var attrs = elems[i].attributes;
48723         tags[attrs.k.value] = attrs.v.value;
48724     }
48725
48726     return tags;
48727 }
48728
48729
48730 function getMembers(obj) {
48731     var elems = obj.getElementsByTagName('member'),
48732         members = new Array(elems.length);
48733     for (var i = 0, l = elems.length; i < l; i++) {
48734         var attrs = elems[i].attributes;
48735         members[i] = {
48736             id: attrs.type.value[0] + attrs.ref.value,
48737             type: attrs.type.value,
48738             role: attrs.role.value
48739         };
48740     }
48741     return members;
48742 }
48743
48744
48745 function getVisible(attrs) {
48746     return (!attrs.visible || attrs.visible.value !== 'false');
48747 }
48748
48749
48750 var parsers = {
48751     node: function nodeData(obj, uid) {
48752         var attrs = obj.attributes;
48753         return new osmNode({
48754             id:uid,
48755             visible: getVisible(attrs),
48756             version: attrs.version.value,
48757             changeset: attrs.changeset && attrs.changeset.value,
48758             timestamp: attrs.timestamp && attrs.timestamp.value,
48759             user: attrs.user && attrs.user.value,
48760             uid: attrs.uid && attrs.uid.value,
48761             loc: getLoc(attrs),
48762             tags: getTags(obj)
48763         });
48764     },
48765
48766     way: function wayData(obj, uid) {
48767         var attrs = obj.attributes;
48768         return new osmWay({
48769             id: uid,
48770             visible: getVisible(attrs),
48771             version: attrs.version.value,
48772             changeset: attrs.changeset && attrs.changeset.value,
48773             timestamp: attrs.timestamp && attrs.timestamp.value,
48774             user: attrs.user && attrs.user.value,
48775             uid: attrs.uid && attrs.uid.value,
48776             tags: getTags(obj),
48777             nodes: getNodes(obj),
48778         });
48779     },
48780
48781     relation: function relationData(obj, uid) {
48782         var attrs = obj.attributes;
48783         return new osmRelation({
48784             id: uid,
48785             visible: getVisible(attrs),
48786             version: attrs.version.value,
48787             changeset: attrs.changeset && attrs.changeset.value,
48788             timestamp: attrs.timestamp && attrs.timestamp.value,
48789             user: attrs.user && attrs.user.value,
48790             uid: attrs.uid && attrs.uid.value,
48791             tags: getTags(obj),
48792             members: getMembers(obj)
48793         });
48794     }
48795 };
48796
48797
48798 function parse$1(xml$$1, callback, options) {
48799     options = lodash.extend({ cache: true }, options);
48800     if (!xml$$1 || !xml$$1.childNodes) return;
48801
48802     var root = xml$$1.childNodes[0],
48803         children = root.childNodes;
48804
48805     function parseChild(child) {
48806         var parser = parsers[child.nodeName];
48807         if (parser) {
48808             var uid = osmEntity$$1.id.fromOSM(child.nodeName, child.attributes.id.value);
48809             if (options.cache && entityCache[uid]) {
48810                 return null;
48811             }
48812             return parser(child, uid);
48813         }
48814     }
48815
48816     utilIdleWorker(children, parseChild, callback);
48817 }
48818
48819
48820 var serviceOsm = {
48821
48822     init: function() {
48823         utilRebind(this, dispatch$3, 'on');
48824     },
48825
48826
48827     reset: function() {
48828         userChangesets = undefined;
48829         userDetails = undefined;
48830         rateLimitError = undefined;
48831         lodash.forEach(inflight$1, abortRequest$1);
48832         entityCache = {};
48833         loadedTiles = {};
48834         inflight$1 = {};
48835         return this;
48836     },
48837
48838
48839     changesetURL: function(changesetId) {
48840         return urlroot + '/changeset/' + changesetId;
48841     },
48842
48843
48844     changesetsURL: function(center, zoom$$1) {
48845         var precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2));
48846         return urlroot + '/history#map=' +
48847             Math.floor(zoom$$1) + '/' +
48848             center[1].toFixed(precision) + '/' +
48849             center[0].toFixed(precision);
48850     },
48851
48852
48853     entityURL: function(entity) {
48854         return urlroot + '/' + entity.type + '/' + entity.osmId();
48855     },
48856
48857
48858     historyURL: function(entity) {
48859         return urlroot + '/' + entity.type + '/' + entity.osmId() + '/history';
48860     },
48861
48862
48863     userURL: function(username) {
48864         return urlroot + '/user/' + username;
48865     },
48866
48867
48868     loadFromAPI: function(path$$1, callback, options) {
48869         options = lodash.extend({ cache: true }, options);
48870         var that = this;
48871
48872         function done(err, xml$$1) {
48873             var isAuthenticated = that.authenticated();
48874
48875             // 400 Bad Request, 401 Unauthorized, 403 Forbidden
48876             // Logout and retry the request..
48877             if (isAuthenticated && err &&
48878                     (err.status === 400 || err.status === 401 || err.status === 403)) {
48879                 that.logout();
48880                 that.loadFromAPI(path$$1, callback);
48881
48882             // else, no retry..
48883             } else {
48884                 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
48885                 // Set the rateLimitError flag and trigger a warning..
48886                 if (!isAuthenticated && !rateLimitError && err &&
48887                         (err.status === 509 || err.status === 429)) {
48888                     rateLimitError = err;
48889                     dispatch$3.call('change');
48890                 }
48891
48892                 if (callback) {
48893                     if (err) return callback(err, null);
48894                     parse$1(xml$$1, function (entities) {
48895                         if (options.cache) {
48896                             for (var i in entities) {
48897                                 entityCache[entities[i].id] = true;
48898                             }
48899                         }
48900                         callback(null, entities);
48901                     }, options);
48902                 }
48903             }
48904         }
48905
48906         if (this.authenticated()) {
48907             return oauth.xhr({ method: 'GET', path: path$$1 }, done);
48908         } else {
48909             var url = urlroot + path$$1;
48910             return xml(url).get(done);
48911         }
48912     },
48913
48914
48915     loadEntity: function(id, callback) {
48916         var type = osmEntity$$1.id.type(id),
48917             osmID = osmEntity$$1.id.toOSM(id),
48918             options = { cache: false };
48919
48920         this.loadFromAPI(
48921             '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
48922             function(err, entities) {
48923                 if (callback) callback(err, { data: entities });
48924             },
48925             options
48926         );
48927     },
48928
48929
48930     loadEntityVersion: function(id, version$$1, callback) {
48931         var type = osmEntity$$1.id.type(id),
48932             osmID = osmEntity$$1.id.toOSM(id),
48933             options = { cache: false };
48934
48935         this.loadFromAPI(
48936             '/api/0.6/' + type + '/' + osmID + '/' + version$$1,
48937             function(err, entities) {
48938                 if (callback) callback(err, { data: entities });
48939             },
48940             options
48941         );
48942     },
48943
48944
48945     loadMultiple: function(ids, callback) {
48946         var that = this;
48947
48948         lodash.each(lodash.groupBy(lodash.uniq(ids), osmEntity$$1.id.type), function(v, k) {
48949             var type = k + 's',
48950                 osmIDs = lodash.map(v, osmEntity$$1.id.toOSM),
48951                 options = { cache: false };
48952
48953             lodash.each(lodash.chunk(osmIDs, 150), function(arr) {
48954                 that.loadFromAPI(
48955                     '/api/0.6/' + type + '?' + type + '=' + arr.join(),
48956                     function(err, entities) {
48957                         if (callback) callback(err, { data: entities });
48958                     },
48959                     options
48960                 );
48961             });
48962         });
48963     },
48964
48965
48966     authenticated: function() {
48967         return oauth.authenticated();
48968     },
48969
48970
48971     putChangeset: function(changeset, changes, callback) {
48972
48973         // Create the changeset..
48974         oauth.xhr({
48975             method: 'PUT',
48976             path: '/api/0.6/changeset/create',
48977             options: { header: { 'Content-Type': 'text/xml' } },
48978             content: JXON.stringify(changeset.asJXON())
48979         }, createdChangeset);
48980
48981
48982         function createdChangeset(err, changeset_id) {
48983             if (err) return callback(err);
48984             changeset = changeset.update({ id: changeset_id });
48985
48986             // Upload the changeset..
48987             oauth.xhr({
48988                 method: 'POST',
48989                 path: '/api/0.6/changeset/' + changeset_id + '/upload',
48990                 options: { header: { 'Content-Type': 'text/xml' } },
48991                 content: JXON.stringify(changeset.osmChangeJXON(changes))
48992             }, uploadedChangeset);
48993         }
48994
48995
48996         function uploadedChangeset(err) {
48997             if (err) return callback(err);
48998
48999             // Upload was successful, safe to call the callback.
49000             // Add delay to allow for postgres replication #1646 #2678
49001             window.setTimeout(function() {
49002                 callback(null, changeset);
49003             }, 2500);
49004
49005             // Still attempt to close changeset, but ignore response because #2667
49006             oauth.xhr({
49007                 method: 'PUT',
49008                 path: '/api/0.6/changeset/' + changeset.id + '/close',
49009                 options: { header: { 'Content-Type': 'text/xml' } }
49010             }, function() { return true; });
49011         }
49012     },
49013
49014
49015     userDetails: function(callback) {
49016         if (userDetails) {
49017             callback(undefined, userDetails);
49018             return;
49019         }
49020
49021         function done(err, user_details) {
49022             if (err) return callback(err);
49023
49024             var u = user_details.getElementsByTagName('user')[0],
49025                 img = u.getElementsByTagName('img'),
49026                 image_url = '';
49027
49028             if (img && img[0] && img[0].getAttribute('href')) {
49029                 image_url = img[0].getAttribute('href');
49030             }
49031
49032             var changesets = u.getElementsByTagName('changesets'),
49033                 changesets_count = 0;
49034
49035             if (changesets && changesets[0] && changesets[0].getAttribute('count')) {
49036                 changesets_count = changesets[0].getAttribute('count');
49037             }
49038
49039             userDetails = {
49040                 id: u.attributes.id.value,
49041                 display_name: u.attributes.display_name.value,
49042                 image_url: image_url,
49043                 changesets_count: changesets_count
49044             };
49045
49046             callback(undefined, userDetails);
49047         }
49048
49049         oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
49050     },
49051
49052
49053     userChangesets: function(callback) {
49054         if (userChangesets) {
49055             callback(undefined, userChangesets);
49056             return;
49057         }
49058
49059         this.userDetails(function(err, user) {
49060             if (err) {
49061                 callback(err);
49062                 return;
49063             }
49064
49065             function done(err, changesets) {
49066                 if (err) {
49067                     callback(err);
49068                 } else {
49069                     userChangesets = Array.prototype.map.call(
49070                         changesets.getElementsByTagName('changeset'),
49071                         function (changeset) {
49072                             return { tags: getTags(changeset) };
49073                         }
49074                     ).filter(function (changeset) {
49075                         var comment = changeset.tags.comment;
49076                         return comment && comment !== '';
49077                     });
49078                     callback(undefined, userChangesets);
49079                 }
49080             }
49081
49082             oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
49083         });
49084     },
49085
49086
49087     status: function(callback) {
49088         function done(xml$$1) {
49089             // update blacklists
49090             var elements = xml$$1.getElementsByTagName('blacklist'),
49091                 regexes = [];
49092             for (var i = 0; i < elements.length; i++) {
49093                 var regex = elements[i].getAttribute('regex');  // needs unencode?
49094                 if (regex) {
49095                     regexes.push(regex);
49096                 }
49097             }
49098             if (regexes.length) {
49099                 blacklists = regexes;
49100             }
49101
49102
49103             if (rateLimitError) {
49104                 callback(rateLimitError, 'rateLimited');
49105             } else {
49106                 var apiStatus = xml$$1.getElementsByTagName('status'),
49107                     val = apiStatus[0].getAttribute('api');
49108
49109                 callback(undefined, val);
49110             }
49111         }
49112
49113         xml(urlroot + '/api/capabilities').get()
49114             .on('load', done)
49115             .on('error', callback);
49116     },
49117
49118
49119     imageryBlacklists: function() {
49120         return blacklists;
49121     },
49122
49123
49124     tileZoom: function(_) {
49125         if (!arguments.length) return tileZoom$1;
49126         tileZoom$1 = _;
49127         return this;
49128     },
49129
49130
49131     loadTiles: function(projection$$1, dimensions, callback) {
49132         if (off) return;
49133
49134         var that = this,
49135             s = projection$$1.scale() * 2 * Math.PI,
49136             z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
49137             ts = 256 * Math.pow(2, z - tileZoom$1),
49138             origin = [
49139                 s / 2 - projection$$1.translate()[0],
49140                 s / 2 - projection$$1.translate()[1]
49141             ];
49142
49143         var tiles = d3geoTile()
49144             .scaleExtent([tileZoom$1, tileZoom$1])
49145             .scale(s)
49146             .size(dimensions)
49147             .translate(projection$$1.translate())()
49148             .map(function(tile) {
49149                 var x = tile[0] * ts - origin[0],
49150                     y = tile[1] * ts - origin[1];
49151
49152                 return {
49153                     id: tile.toString(),
49154                     extent: geoExtent$$1(
49155                         projection$$1.invert([x, y + ts]),
49156                         projection$$1.invert([x + ts, y]))
49157                 };
49158             });
49159
49160         lodash.filter(inflight$1, function(v, i) {
49161             var wanted = lodash.find(tiles, function(tile) {
49162                 return i === tile.id;
49163             });
49164             if (!wanted) delete inflight$1[i];
49165             return !wanted;
49166         }).map(abortRequest$1);
49167
49168         tiles.forEach(function(tile) {
49169             var id = tile.id;
49170
49171             if (loadedTiles[id] || inflight$1[id]) return;
49172
49173             if (lodash.isEmpty(inflight$1)) {
49174                 dispatch$3.call('loading');
49175             }
49176
49177             inflight$1[id] = that.loadFromAPI(
49178                 '/api/0.6/map?bbox=' + tile.extent.toParam(),
49179                 function(err, parsed) {
49180                     delete inflight$1[id];
49181                     if (!err) {
49182                         loadedTiles[id] = true;
49183                     }
49184
49185                     if (callback) {
49186                         callback(err, lodash.extend({ data: parsed }, tile));
49187                     }
49188
49189                     if (lodash.isEmpty(inflight$1)) {
49190                         dispatch$3.call('loaded');
49191                     }
49192                 }
49193             );
49194         });
49195     },
49196
49197
49198     switch: function(options) {
49199         urlroot = options.urlroot;
49200
49201         oauth.options(lodash.extend({
49202             url: urlroot,
49203             loading: authLoading,
49204             done: authDone
49205         }, options));
49206
49207         dispatch$3.call('change');
49208         this.reset();
49209         this.userChangesets(function() {});  // eagerly load user details/changesets
49210         return this;
49211     },
49212
49213
49214     toggle: function(_) {
49215         off = !_;
49216         return this;
49217     },
49218
49219
49220     loadedTiles: function(_) {
49221         if (!arguments.length) return loadedTiles;
49222         loadedTiles = _;
49223         return this;
49224     },
49225
49226
49227     logout: function() {
49228         userChangesets = undefined;
49229         userDetails = undefined;
49230         oauth.logout();
49231         dispatch$3.call('change');
49232         return this;
49233     },
49234
49235
49236     authenticate: function(callback) {
49237         var that = this;
49238         userChangesets = undefined;
49239         userDetails = undefined;
49240
49241         function done(err, res) {
49242             rateLimitError = undefined;
49243             dispatch$3.call('change');
49244             if (callback) callback(err, res);
49245             that.userChangesets(function() {});  // eagerly load user details/changesets
49246         }
49247
49248         return oauth.authenticate(done);
49249     }
49250 };
49251
49252 var apibase$2 = 'https://taginfo.openstreetmap.org/api/4/';
49253 var inflight$2 = {};
49254 var popularKeys = {};
49255 var taginfoCache = {};
49256 var tag_sorts = {
49257         point: 'count_nodes',
49258         vertex: 'count_nodes',
49259         area: 'count_ways',
49260         line: 'count_ways'
49261     };
49262 var tag_sort_members = {
49263         point: 'count_node_members',
49264         vertex: 'count_node_members',
49265         area: 'count_way_members',
49266         line: 'count_way_members',
49267         relation: 'count_relation_members'
49268     };
49269 var tag_filters = {
49270         point: 'nodes',
49271         vertex: 'nodes',
49272         area: 'ways',
49273         line: 'ways'
49274     };
49275 var tag_members_fractions = {
49276         point: 'count_node_members_fraction',
49277         vertex: 'count_node_members_fraction',
49278         area: 'count_way_members_fraction',
49279         line: 'count_way_members_fraction',
49280         relation: 'count_relation_members_fraction'
49281     };
49282
49283
49284 function sets(params, n, o) {
49285     if (params.geometry && o[params.geometry]) {
49286         params[n] = o[params.geometry];
49287     }
49288     return params;
49289 }
49290
49291
49292 function setFilter(params) {
49293     return sets(params, 'filter', tag_filters);
49294 }
49295
49296
49297 function setSort(params) {
49298     return sets(params, 'sortname', tag_sorts);
49299 }
49300
49301
49302 function setSortMembers(params) {
49303     return sets(params, 'sortname', tag_sort_members);
49304 }
49305
49306
49307 function clean(params) {
49308     return lodash.omit(params, ['geometry', 'debounce']);
49309 }
49310
49311
49312 function filterKeys(type) {
49313     var count_type = type ? 'count_' + type : 'count_all';
49314     return function(d) {
49315         return parseFloat(d[count_type]) > 2500 || d.in_wiki;
49316     };
49317 }
49318
49319
49320 function filterMultikeys(prefix) {
49321     return function(d) {
49322         // d.key begins with prefix, and d.key contains no additional ':'s
49323         var re = new RegExp('^' + prefix + '(.*)$');
49324         var matches = d.key.match(re) || [];
49325         return (matches.length === 2 && matches[1].indexOf(':') === -1);
49326     };
49327 }
49328
49329
49330 function filterValues(allowUpperCase) {
49331     return function(d) {
49332         if (d.value.match(/[;,]/) !== null) return false;  // exclude some punctuation
49333         if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false;  // exclude uppercase letters
49334         return parseFloat(d.fraction) > 0.0 || d.in_wiki;
49335     };
49336 }
49337
49338
49339 function filterRoles(geometry) {
49340     return function(d) {
49341         if (d.role === '') return false; // exclude empty role
49342         if (d.role.match(/[A-Z*;,]/) !== null) return false;  // exclude uppercase letters and some punctuation
49343         return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
49344     };
49345 }
49346
49347
49348 function valKey(d) {
49349     return {
49350         value: d.key,
49351         title: d.key
49352     };
49353 }
49354
49355
49356 function valKeyDescription(d) {
49357     return {
49358         value: d.value,
49359         title: d.description || d.value
49360     };
49361 }
49362
49363
49364 function roleKey(d) {
49365     return {
49366         value: d.role,
49367         title: d.role
49368     };
49369 }
49370
49371
49372 // sort keys with ':' lower than keys without ':'
49373 function sortKeys(a, b) {
49374     return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
49375         : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
49376         : 0;
49377 }
49378
49379
49380 var debouncedRequest = lodash.debounce(request$1, 500, { leading: false });
49381
49382 function request$1(url, params, exactMatch, callback, loaded) {
49383     if (inflight$2[url]) return;
49384
49385     if (checkCache(url, params, exactMatch, callback)) return;
49386
49387     inflight$2[url] = json(url, function (err, data) {
49388         delete inflight$2[url];
49389         loaded(err, data);
49390     });
49391 }
49392
49393
49394 function checkCache(url, params, exactMatch, callback) {
49395     var rp = params.rp || 25,
49396         testQuery = params.query || '',
49397         testUrl = url;
49398
49399     do {
49400         var hit = taginfoCache[testUrl];
49401
49402         // exact match, or shorter match yielding fewer than max results (rp)
49403         if (hit && (url === testUrl || hit.length < rp)) {
49404             callback(null, hit);
49405             return true;
49406         }
49407
49408         // don't try to shorten the query
49409         if (exactMatch || !testQuery.length) return false;
49410
49411         // do shorten the query to see if we already have a cached result
49412         // that has returned fewer than max results (rp)
49413         testQuery = testQuery.slice(0, -1);
49414         testUrl = url.replace(/&query=(.*?)&/, '&query=' + testQuery + '&');
49415     } while (testQuery.length >= 0);
49416
49417     return false;
49418 }
49419
49420
49421 var serviceTaginfo = {
49422
49423     init: function() {
49424         inflight$2 = {};
49425         taginfoCache = {};
49426         popularKeys = {};
49427
49428         // Fetch popular keys.  We'll exclude these from `values`
49429         // lookups because they stress taginfo, and they aren't likely
49430         // to yield meaningful autocomplete results.. see #3955
49431         var params = { rp: 100, sortname: 'values_all', sortorder: 'desc', page: 1, debounce: false };
49432         this.keys(params, function(err, data) {
49433             if (err) return;
49434             data.forEach(function(d) {
49435                 if (d.value === 'opening_hours') return;  // exception
49436                 popularKeys[d.value] = true;
49437             });
49438         });
49439     },
49440
49441
49442     reset: function() {
49443         lodash.forEach(inflight$2, function(req) { req.abort(); });
49444         inflight$2 = {};
49445     },
49446
49447
49448     keys: function(params, callback) {
49449         var doRequest = params.debounce ? debouncedRequest : request$1;
49450         params = clean(setSort(params));
49451         params = lodash.extend({ rp: 10, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
49452
49453         var url = apibase$2 + 'keys/all?' + utilQsString(params);
49454         doRequest(url, params, false, callback, function(err, d) {
49455             if (err) {
49456                 callback(err);
49457             } else {
49458                 var f = filterKeys(params.filter);
49459                 var result = d.data.filter(f).sort(sortKeys).map(valKey);
49460                 taginfoCache[url] = result;
49461                 callback(null, result);
49462             }
49463         });
49464     },
49465
49466
49467     multikeys: function(params, callback) {
49468         var doRequest = params.debounce ? debouncedRequest : request$1;
49469         params = clean(setSort(params));
49470         params = lodash.extend({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
49471         var prefix = params.query;
49472
49473         var url = apibase$2 + 'keys/all?' + utilQsString(params);
49474         doRequest(url, params, true, callback, function(err, d) {
49475             if (err) {
49476                 callback(err);
49477             } else {
49478                 var f = filterMultikeys(prefix);
49479                 var result = d.data.filter(f).map(valKey);
49480                 taginfoCache[url] = result;
49481                 callback(null, result);
49482             }
49483         });
49484     },
49485
49486
49487     values: function(params, callback) {
49488         // Exclude popular keys from values lookups.. see #3955
49489         var key = params.key;
49490         if (key && popularKeys[key]) {
49491             callback(null, []);
49492             return;
49493         }
49494
49495         var doRequest = params.debounce ? debouncedRequest : request$1;
49496         params = clean(setSort(setFilter(params)));
49497         params = lodash.extend({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
49498
49499         var url = apibase$2 + 'key/values?' + utilQsString(params);
49500         doRequest(url, params, false, callback, function(err, d) {
49501             if (err) {
49502                 callback(err);
49503             } else {
49504                 // In most cases we prefer taginfo value results with lowercase letters.
49505                 // A few OSM keys expect values to contain uppercase values (see #3377).
49506                 // This is not an exhaustive list (e.g. `name` also has uppercase values)
49507                 // but these are the fields where taginfo value lookup is most useful.
49508                 var re = /network|taxon|genus|species|brand|grape_variety|_hours|_times/;
49509                 var allowUpperCase = (params.key.match(re) !== null);
49510                 var f = filterValues(allowUpperCase);
49511
49512                 var result = d.data.filter(f).map(valKeyDescription);
49513                 taginfoCache[url] = result;
49514                 callback(null, result);
49515             }
49516         });
49517     },
49518
49519
49520     roles: function(params, callback) {
49521         var doRequest = params.debounce ? debouncedRequest : request$1;
49522         var geometry = params.geometry;
49523         params = clean(setSortMembers(params));
49524         params = lodash.extend({ rp: 25, sortname: 'count_all_members', sortorder: 'desc', page: 1 }, params);
49525
49526         var url = apibase$2 + 'relation/roles?' + utilQsString(params);
49527         doRequest(url, params, true, callback, function(err, d) {
49528             if (err) {
49529                 callback(err);
49530             } else {
49531                 var f = filterRoles(geometry);
49532                 var result = d.data.filter(f).map(roleKey);
49533                 taginfoCache[url] = result;
49534                 callback(null, result);
49535             }
49536         });
49537     },
49538
49539
49540     docs: function(params, callback) {
49541         var doRequest = params.debounce ? debouncedRequest : request$1;
49542         params = clean(setSort(params));
49543
49544         var path$$1 = 'key/wiki_pages?';
49545         if (params.value) path$$1 = 'tag/wiki_pages?';
49546         else if (params.rtype) path$$1 = 'relation/wiki_pages?';
49547
49548         var url = apibase$2 + path$$1 + utilQsString(params);
49549         doRequest(url, params, true, callback, function(err, d) {
49550             if (err) {
49551                 callback(err);
49552             } else {
49553                 taginfoCache[url] = d.data;
49554                 callback(null, d.data);
49555             }
49556         });
49557     },
49558
49559
49560     apibase: function(_) {
49561         if (!arguments.length) return apibase$2;
49562         apibase$2 = _;
49563         return this;
49564     }
49565
49566 };
49567
49568 var jsonpCache = {};
49569 window.jsonpCache = jsonpCache;
49570
49571 function jsonpRequest(url, callback) {
49572
49573   if (window.JSONP_FIX) {
49574     if (window.JSONP_DELAY === 0) {
49575       callback(window.JSONP_FIX);
49576     } else {
49577       setTimeout(function() {
49578         callback(window.JSONP_FIX);
49579       }, window.JSONP_DELAY || 0);
49580     }
49581     return;
49582   }
49583
49584   function rand() {
49585     var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
49586       c = '', i = -1;
49587     while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
49588     return c;
49589   }
49590
49591   function create(url) {
49592     var e = url.match(/callback=(\w+)/),
49593       c = e ? e[1] : rand();
49594     jsonpCache[c] = function(data) {
49595       callback(data);
49596       delete jsonpCache[c];
49597       script.remove();
49598     };
49599     return 'jsonpCache.' + c;
49600   }
49601
49602   var cb = create(url),
49603     script = select('head')
49604     .append('script')
49605     .attr('type', 'text/javascript')
49606     .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
49607 }
49608
49609 var endpoint = 'https://www.wikidata.org/w/api.php?';
49610
49611 var serviceWikidata = {
49612
49613     init: function() {},
49614     reset: function() {},
49615
49616
49617     // Given a Wikipedia language and article title, return an array of
49618     // corresponding Wikidata entities.
49619     itemsByTitle: function(lang, title, callback) {
49620         if (!title) {
49621             callback('', {});
49622             return;
49623         }
49624
49625         lang = lang || 'en';
49626         jsonpRequest(endpoint + utilQsString({
49627             action: 'wbgetentities',
49628             format: 'json',
49629             sites: lang.replace(/-/g, '_') + 'wiki',
49630             titles: title,
49631             languages: 'en', // shrink response by filtering to one language
49632             callback: '{callback}'
49633         }), function(data) {
49634             if (!data || data.error) {
49635                 callback('', {});
49636             } else {
49637                 callback(title, data.entities || {});
49638             }
49639         });
49640     }
49641
49642 };
49643
49644 var endpoint$1 = 'https://en.wikipedia.org/w/api.php?';
49645
49646 var serviceWikipedia = {
49647
49648     init: function() {},
49649     reset: function() {},
49650
49651
49652     search: function(lang, query, callback) {
49653         if (!query) {
49654             callback('', []);
49655             return;
49656         }
49657
49658         lang = lang || 'en';
49659         jsonpRequest(endpoint$1.replace('en', lang) +
49660             utilQsString({
49661                 action: 'query',
49662                 list: 'search',
49663                 srlimit: '10',
49664                 srinfo: 'suggestion',
49665                 format: 'json',
49666                 callback: '{callback}',
49667                 srsearch: query
49668             }), function(data) {
49669                 if (!data || !data.query || !data.query.search || data.error) {
49670                     callback('', []);
49671                 } else {
49672                     var results = data.query.search.map(function(d) { return d.title; });
49673                     callback(query, results);
49674                 }
49675             }
49676         );
49677     },
49678
49679
49680     suggestions: function(lang, query, callback) {
49681         if (!query) {
49682             callback('', []);
49683             return;
49684         }
49685
49686         lang = lang || 'en';
49687         jsonpRequest(endpoint$1.replace('en', lang) +
49688             utilQsString({
49689                 action: 'opensearch',
49690                 namespace: 0,
49691                 suggest: '',
49692                 format: 'json',
49693                 callback: '{callback}',
49694                 search: query
49695             }), function(data) {
49696                 if (!data || data.error) {
49697                     callback('', []);
49698                 } else {
49699                     callback(data[0], data[1] || []);
49700                 }
49701             }
49702         );
49703     },
49704
49705
49706     translations: function(lang, title, callback) {
49707         if (!title) {
49708             callback({});
49709             return;
49710         }
49711
49712         jsonpRequest(endpoint$1.replace('en', lang) +
49713             utilQsString({
49714                 action: 'query',
49715                 prop: 'langlinks',
49716                 format: 'json',
49717                 callback: '{callback}',
49718                 lllimit: 500,
49719                 titles: title
49720             }), function(data) {
49721                 if (!data || !data.query || !data.query.pages || data.error) {
49722                     callback({});
49723                 } else {
49724                     var list = data.query.pages[Object.keys(data.query.pages)[0]],
49725                         translations = {};
49726                     if (list && list.langlinks) {
49727                         list.langlinks.forEach(function(d) {
49728                             translations[d.lang] = d['*'];
49729                         });
49730                     }
49731                     callback(translations);
49732                 }
49733             }
49734         );
49735     }
49736
49737 };
49738
49739 var services = {
49740     mapillary: serviceMapillary,
49741     geocoder: serviceNominatim,
49742     osm: serviceOsm,
49743     taginfo: serviceTaginfo,
49744     wikidata: serviceWikidata,
49745     wikipedia: serviceWikipedia
49746 };
49747
49748 function svgMapillaryImages(projection$$1, context, dispatch$$1) {
49749     var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
49750         minZoom = 12,
49751         minViewfieldZoom = 17,
49752         layer = select(null),
49753         _mapillary;
49754
49755
49756     function init() {
49757         if (svgMapillaryImages.initialized) return;  // run once
49758         svgMapillaryImages.enabled = false;
49759         svgMapillaryImages.initialized = true;
49760     }
49761
49762
49763     function getMapillary() {
49764         if (services.mapillary && !_mapillary) {
49765             _mapillary = services.mapillary;
49766             _mapillary.event.on('loadedImages', throttledRedraw);
49767         } else if (!services.mapillary && _mapillary) {
49768             _mapillary = null;
49769         }
49770
49771         return _mapillary;
49772     }
49773
49774
49775     function showLayer() {
49776         var mapillary = getMapillary();
49777         if (!mapillary) return;
49778
49779         mapillary.loadViewer(context);
49780         editOn();
49781
49782         layer
49783             .style('opacity', 0)
49784             .transition()
49785             .duration(500)
49786             .style('opacity', 1)
49787             .on('end', function () { dispatch$$1.call('change'); });
49788     }
49789
49790
49791     function hideLayer() {
49792         var mapillary = getMapillary();
49793         if (mapillary) {
49794             mapillary.hideViewer();
49795         }
49796
49797         throttledRedraw.cancel();
49798
49799         layer
49800             .transition()
49801             .duration(500)
49802             .style('opacity', 0)
49803             .on('end', editOff);
49804     }
49805
49806
49807     function editOn() {
49808         layer.style('display', 'block');
49809     }
49810
49811
49812     function editOff() {
49813         layer.selectAll('.viewfield-group').remove();
49814         layer.style('display', 'none');
49815     }
49816
49817
49818     function click(d) {
49819         var mapillary = getMapillary();
49820         if (!mapillary) return;
49821
49822         context.map().centerEase(d.loc);
49823
49824         mapillary
49825             .selectedImage(d.key, true)
49826             .updateViewer(d.key, context)
49827             .showViewer();
49828     }
49829
49830
49831     function transform$$1(d) {
49832         var t = svgPointTransform(projection$$1)(d);
49833         if (d.ca) t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
49834         return t;
49835     }
49836
49837
49838     function update() {
49839         var mapillary = getMapillary(),
49840             data = (mapillary ? mapillary.images(projection$$1) : []),
49841             imageKey = mapillary ? mapillary.selectedImage() : null;
49842
49843         var markers = layer.selectAll('.viewfield-group')
49844             .data(data, function(d) { return d.key; });
49845
49846         markers.exit()
49847             .remove();
49848
49849         var enter = markers.enter()
49850             .append('g')
49851             .attr('class', 'viewfield-group')
49852             .classed('selected', function(d) { return d.key === imageKey; })
49853             .on('click', click);
49854
49855         markers = markers
49856             .merge(enter)
49857             .attr('transform', transform$$1);
49858
49859
49860        var viewfields = markers.selectAll('.viewfield')
49861             .data(~~context.map().zoom() >= minViewfieldZoom ? [0] : []);
49862
49863         viewfields.exit()
49864             .remove();
49865
49866         viewfields.enter()
49867             .append('path')
49868             .attr('class', 'viewfield')
49869             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
49870             .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');
49871
49872         markers.selectAll('circle')
49873             .data([0])
49874             .enter()
49875             .append('circle')
49876             .attr('dx', '0')
49877             .attr('dy', '0')
49878             .attr('r', '6');
49879     }
49880
49881
49882     function drawImages(selection$$1) {
49883         var enabled = svgMapillaryImages.enabled,
49884             mapillary = getMapillary();
49885
49886         layer = selection$$1.selectAll('.layer-mapillary-images')
49887             .data(mapillary ? [0] : []);
49888
49889         layer.exit()
49890             .remove();
49891
49892         layer = layer.enter()
49893             .append('g')
49894             .attr('class', 'layer-mapillary-images')
49895             .style('display', enabled ? 'block' : 'none')
49896             .merge(layer);
49897
49898         if (enabled) {
49899             if (mapillary && ~~context.map().zoom() >= minZoom) {
49900                 editOn();
49901                 update();
49902                 mapillary.loadImages(projection$$1);
49903             } else {
49904                 editOff();
49905             }
49906         }
49907     }
49908
49909
49910     drawImages.enabled = function(_) {
49911         if (!arguments.length) return svgMapillaryImages.enabled;
49912         svgMapillaryImages.enabled = _;
49913         if (svgMapillaryImages.enabled) {
49914             showLayer();
49915         } else {
49916             hideLayer();
49917         }
49918         dispatch$$1.call('change');
49919         return this;
49920     };
49921
49922
49923     drawImages.supported = function() {
49924         return !!getMapillary();
49925     };
49926
49927
49928     init();
49929     return drawImages;
49930 }
49931
49932 function svgMapillarySigns(projection$$1, context, dispatch$$1) {
49933     var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
49934         minZoom = 12,
49935         layer = select(null),
49936         _mapillary;
49937
49938
49939     function init() {
49940         if (svgMapillarySigns.initialized) return;  // run once
49941         svgMapillarySigns.enabled = false;
49942         svgMapillarySigns.initialized = true;
49943     }
49944
49945
49946     function getMapillary() {
49947         if (services.mapillary && !_mapillary) {
49948             _mapillary = services.mapillary;
49949             _mapillary.event.on('loadedSigns', throttledRedraw);
49950         } else if (!services.mapillary && _mapillary) {
49951             _mapillary = null;
49952         }
49953         return _mapillary;
49954     }
49955
49956
49957     function showLayer() {
49958         editOn();
49959     }
49960
49961
49962     function hideLayer() {
49963         throttledRedraw.cancel();
49964         editOff();
49965     }
49966
49967
49968     function editOn() {
49969         layer.style('display', 'block');
49970     }
49971
49972
49973     function editOff() {
49974         layer.selectAll('.icon-sign').remove();
49975         layer.style('display', 'none');
49976     }
49977
49978
49979     function click(d) {
49980         var mapillary = getMapillary();
49981         if (!mapillary) return;
49982
49983         context.map().centerEase(d.loc);
49984
49985         var selected = mapillary.selectedImage(),
49986             imageKey;
49987
49988         // Pick one of the images the sign was detected in,
49989         // preference given to an image already selected.
49990         d.detections.forEach(function(detection) {
49991             if (!imageKey || selected === detection.image_key) {
49992                 imageKey = detection.image_key;
49993             }
49994         });
49995
49996         mapillary
49997             .selectedImage(imageKey, true)
49998             .updateViewer(imageKey, context)
49999             .showViewer();
50000     }
50001
50002
50003     function update() {
50004         var mapillary = getMapillary(),
50005             data = (mapillary ? mapillary.signs(projection$$1) : []),
50006             imageKey = mapillary ? mapillary.selectedImage() : null;
50007
50008         var signs = layer.selectAll('.icon-sign')
50009             .data(data, function(d) { return d.key; });
50010
50011         signs.exit()
50012             .remove();
50013
50014         var enter = signs.enter()
50015             .append('foreignObject')
50016             .attr('class', 'icon-sign')
50017             .attr('width', '24px')      // for Firefox
50018             .attr('height', '24px')     // for Firefox
50019             .classed('selected', function(d) {
50020                 return lodash.some(d.detections, function(detection) {
50021                     return detection.image_key === imageKey;
50022                 });
50023             })
50024             .on('click', click);
50025
50026         enter
50027             .append('xhtml:body')
50028             .attr('class', 'icon-sign-body')
50029             .html(mapillary.signHTML);
50030
50031         signs
50032             .merge(enter)
50033             .attr('x', function(d) { return projection$$1(d.loc)[0] - 12; })   // offset by -12px to
50034             .attr('y', function(d) { return projection$$1(d.loc)[1] - 12; });  // center signs on loc
50035     }
50036
50037
50038     function drawSigns(selection$$1) {
50039         var enabled = svgMapillarySigns.enabled,
50040             mapillary = getMapillary();
50041
50042         layer = selection$$1.selectAll('.layer-mapillary-signs')
50043             .data(mapillary ? [0] : []);
50044
50045         layer.exit()
50046             .remove();
50047
50048         layer = layer.enter()
50049             .append('g')
50050             .attr('class', 'layer-mapillary-signs')
50051             .style('display', enabled ? 'block' : 'none')
50052             .merge(layer);
50053
50054         if (enabled) {
50055             if (mapillary && ~~context.map().zoom() >= minZoom) {
50056                 editOn();
50057                 update();
50058                 mapillary.loadSigns(context, projection$$1);
50059             } else {
50060                 editOff();
50061             }
50062         }
50063     }
50064
50065
50066     drawSigns.enabled = function(_) {
50067         if (!arguments.length) return svgMapillarySigns.enabled;
50068         svgMapillarySigns.enabled = _;
50069         if (svgMapillarySigns.enabled) {
50070             showLayer();
50071         } else {
50072             hideLayer();
50073         }
50074         dispatch$$1.call('change');
50075         return this;
50076     };
50077
50078
50079     drawSigns.supported = function() {
50080         var mapillary = getMapillary();
50081         return (mapillary && mapillary.signsSupported());
50082     };
50083
50084
50085     init();
50086     return drawSigns;
50087 }
50088
50089 function svgOsm() {
50090     return function drawOsm(selection) {
50091         var layers = selection.selectAll('.layer-osm')
50092             .data(['areas', 'lines', 'hit', 'halo', 'label']);
50093
50094         layers.enter()
50095             .append('g')
50096             .attr('class', function(d) { return 'layer-osm layer-' + d; });
50097     };
50098 }
50099
50100 function svgLayers(projection$$1, context) {
50101     var dispatch$$1 = dispatch('change'),
50102         svg = select(null),
50103         layers = [
50104             { id: 'osm', layer: svgOsm(projection$$1, context, dispatch$$1) },
50105             { id: 'gpx', layer: svgGpx(projection$$1, context, dispatch$$1) },
50106             { id: 'mapillary-images', layer: svgMapillaryImages(projection$$1, context, dispatch$$1) },
50107             { id: 'mapillary-signs',  layer: svgMapillarySigns(projection$$1, context, dispatch$$1) },
50108             { id: 'debug', layer: svgDebug(projection$$1, context, dispatch$$1) }
50109         ];
50110
50111
50112     function drawLayers(selection$$1) {
50113         svg = selection$$1.selectAll('.surface')
50114             .data([0]);
50115
50116         svg = svg.enter()
50117             .append('svg')
50118             .attr('class', 'surface')
50119             .merge(svg);
50120
50121         var defs = svg.selectAll('.surface-defs')
50122             .data([0]);
50123
50124         defs.enter()
50125             .append('defs')
50126             .attr('class', 'surface-defs');
50127
50128         var groups = svg.selectAll('.data-layer')
50129             .data(layers);
50130
50131         groups.exit()
50132             .remove();
50133
50134         groups.enter()
50135             .append('g')
50136             .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
50137             .merge(groups)
50138             .each(function(d) { select(this).call(d.layer); });
50139     }
50140
50141
50142     drawLayers.all = function() {
50143         return layers;
50144     };
50145
50146
50147     drawLayers.layer = function(id) {
50148         var obj = lodash.find(layers, function(o) {return o.id === id;});
50149         return obj && obj.layer;
50150     };
50151
50152
50153     drawLayers.only = function(what) {
50154         var arr = [].concat(what);
50155         drawLayers.remove(lodash.difference(lodash.map(layers, 'id'), arr));
50156         return this;
50157     };
50158
50159
50160     drawLayers.remove = function(what) {
50161         var arr = [].concat(what);
50162         arr.forEach(function(id) {
50163             layers = lodash.reject(layers, function(o) {return o.id === id;});
50164         });
50165         dispatch$$1.call('change');
50166         return this;
50167     };
50168
50169
50170     drawLayers.add = function(what) {
50171         var arr = [].concat(what);
50172         arr.forEach(function(obj) {
50173             if ('id' in obj && 'layer' in obj) {
50174                 layers.push(obj);
50175             }
50176         });
50177         dispatch$$1.call('change');
50178         return this;
50179     };
50180
50181
50182     drawLayers.dimensions = function(_) {
50183         if (!arguments.length) return utilGetDimensions(svg);
50184         utilSetDimensions(svg, _);
50185         return this;
50186     };
50187
50188
50189     return utilRebind(drawLayers, dispatch$$1, 'on');
50190 }
50191
50192 function svgLines$$1(projection$$1, context) {
50193     var detected = utilDetect();
50194
50195     var highway_stack = {
50196         motorway: 0,
50197         motorway_link: 1,
50198         trunk: 2,
50199         trunk_link: 3,
50200         primary: 4,
50201         primary_link: 5,
50202         secondary: 6,
50203         tertiary: 7,
50204         unclassified: 8,
50205         residential: 9,
50206         service: 10,
50207         footway: 11
50208     };
50209
50210
50211     function drawLines(selection$$1, graph, entities, filter) {
50212
50213
50214         function waystack(a, b) {
50215             var selected = context.selectedIDs(),
50216                 scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0,
50217                 scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
50218
50219             if (a.tags.highway) { scoreA -= highway_stack[a.tags.highway]; }
50220             if (b.tags.highway) { scoreB -= highway_stack[b.tags.highway]; }
50221             return scoreA - scoreB;
50222         }
50223
50224
50225         function drawLineGroup(selection$$1, klass, isSelected) {
50226             var lines = selection$$1
50227                 .selectAll('path')
50228                 .filter(filter)
50229                 .data(getPathData(isSelected), osmEntity$$1.key);
50230
50231             lines.exit()
50232                 .remove();
50233
50234             // Optimization: call simple TagClasses only on enter selection. This
50235             // works because osmEntity.key is defined to include the entity v attribute.
50236             lines.enter()
50237                 .append('path')
50238                 .attr('class', function(d) {
50239                     return 'way line ' + klass + ' ' + d.id + (isSelected ? ' selected' : '') +
50240                         (oldMultiPolygonOuters[d.id] ? ' old-multipolygon' : '');
50241                 })
50242                 .call(svgTagClasses())
50243                 .merge(lines)
50244                 .sort(waystack)
50245                 .attr('d', getPath)
50246                 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
50247
50248             return selection$$1;
50249         }
50250
50251
50252         function getPathData(isSelected) {
50253             return function() {
50254                 var layer = this.parentNode.__data__;
50255                 var data = pathdata[layer] || [];
50256                 return data.filter(function(d) {
50257                     if (isSelected)
50258                         return context.selectedIDs().indexOf(d.id) !== -1;
50259                     else
50260                         return context.selectedIDs().indexOf(d.id) === -1;
50261                 });
50262             };
50263         }
50264
50265
50266         var getPath = svgPath(projection$$1, graph),
50267             ways = [],
50268             pathdata = {},
50269             onewaydata = {},
50270             oldMultiPolygonOuters = {};
50271
50272         for (var i = 0; i < entities.length; i++) {
50273             var entity = entities[i],
50274                 outer = osmSimpleMultipolygonOuterMember(entity, graph);
50275             if (outer) {
50276                 ways.push(entity.mergeTags(outer.tags));
50277                 oldMultiPolygonOuters[outer.id] = true;
50278             } else if (entity.geometry(graph) === 'line') {
50279                 ways.push(entity);
50280             }
50281         }
50282
50283         ways = ways.filter(getPath);
50284         pathdata = lodash.groupBy(ways, function(way) { return way.layer(); });
50285
50286         lodash.forOwn(pathdata, function(v, k) {
50287             onewaydata[k] = lodash(v)
50288                 .filter(function(d) { return d.isOneWay(); })
50289                 .map(svgOneWaySegments(projection$$1, graph, 35))
50290                 .flatten()
50291                 .valueOf();
50292         });
50293
50294
50295         var layer = selection$$1.selectAll('.layer-lines');
50296
50297         var layergroup = layer
50298             .selectAll('g.layergroup')
50299             .data(sequence(-10, 11));
50300
50301         layergroup = layergroup.enter()
50302             .append('g')
50303             .attr('class', function(d) { return 'layergroup layer' + String(d); })
50304             .merge(layergroup);
50305
50306         layergroup
50307             .selectAll('g.linegroup')
50308             .data(['shadow', 'casing', 'stroke', 'shadow-highlighted', 'casing-highlighted', 'stroke-highlighted'])
50309             .enter()
50310             .append('g')
50311             .attr('class', function(d) { return 'linegroup line-' + d; });
50312
50313
50314         layergroup.selectAll('g.line-shadow')
50315             .call(drawLineGroup, 'shadow', false);
50316         layergroup.selectAll('g.line-casing')
50317             .call(drawLineGroup, 'casing', false);
50318         layergroup.selectAll('g.line-stroke')
50319             .call(drawLineGroup, 'stroke', false);
50320
50321         layergroup.selectAll('g.line-shadow-highlighted')
50322             .call(drawLineGroup, 'shadow', true);
50323         layergroup.selectAll('g.line-casing-highlighted')
50324             .call(drawLineGroup, 'casing', true);
50325         layergroup.selectAll('g.line-stroke-highlighted')
50326             .call(drawLineGroup, 'stroke', true);
50327
50328
50329         var onewaygroup = layergroup
50330             .selectAll('g.onewaygroup')
50331             .data(['oneway']);
50332
50333         onewaygroup = onewaygroup.enter()
50334             .append('g')
50335             .attr('class', 'onewaygroup')
50336             .merge(onewaygroup);
50337
50338         var oneways = onewaygroup
50339             .selectAll('path')
50340             .filter(filter)
50341             .data(
50342                 function() { return onewaydata[this.parentNode.__data__] || []; },
50343                 function(d) { return [d.id, d.index]; }
50344             );
50345
50346         oneways.exit()
50347             .remove();
50348
50349         oneways = oneways.enter()
50350             .append('path')
50351             .attr('class', 'oneway')
50352             .attr('marker-mid', 'url(#oneway-marker)')
50353             .merge(oneways)
50354             .attr('d', function(d) { return d.d; });
50355
50356         if (detected.ie) {
50357             oneways.each(function() { this.parentNode.insertBefore(this, this); });
50358         }
50359     }
50360
50361
50362     return drawLines;
50363 }
50364
50365 function svgMidpoints$$1(projection, context) {
50366
50367     return function drawMidpoints(selection, graph, entities, filter, extent) {
50368         var layer = selection.selectAll('.layer-hit');
50369
50370         var mode = context.mode();
50371         if (mode && mode.id !== 'select') {
50372             layer.selectAll('g.midpoint').remove();
50373             return;
50374         }
50375
50376         var poly = extent.polygon(),
50377             midpoints = {};
50378
50379         for (var i = 0; i < entities.length; i++) {
50380             var entity = entities[i];
50381
50382             if (entity.type !== 'way')
50383                 continue;
50384             if (!filter(entity))
50385                 continue;
50386             if (context.selectedIDs().indexOf(entity.id) < 0)
50387                 continue;
50388
50389             var nodes = graph.childNodes(entity);
50390             for (var j = 0; j < nodes.length - 1; j++) {
50391
50392                 var a = nodes[j],
50393                     b = nodes[j + 1],
50394                     id = [a.id, b.id].sort().join('-');
50395
50396                 if (midpoints[id]) {
50397                     midpoints[id].parents.push(entity);
50398                 } else {
50399                     if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
50400                         var point = geoInterp(a.loc, b.loc, 0.5),
50401                             loc = null;
50402
50403                         if (extent.intersects(point)) {
50404                             loc = point;
50405                         } else {
50406                             for (var k = 0; k < 4; k++) {
50407                                 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
50408                                 if (point &&
50409                                     geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
50410                                     geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
50411                                 {
50412                                     loc = point;
50413                                     break;
50414                                 }
50415                             }
50416                         }
50417
50418                         if (loc) {
50419                             midpoints[id] = {
50420                                 type: 'midpoint',
50421                                 id: id,
50422                                 loc: loc,
50423                                 edge: [a.id, b.id],
50424                                 parents: [entity]
50425                             };
50426                         }
50427                     }
50428                 }
50429             }
50430         }
50431
50432
50433         function midpointFilter(d) {
50434             if (midpoints[d.id])
50435                 return true;
50436
50437             for (var i = 0; i < d.parents.length; i++) {
50438                 if (filter(d.parents[i])) {
50439                     return true;
50440                 }
50441             }
50442
50443             return false;
50444         }
50445
50446
50447         var groups = layer
50448             .selectAll('g.midpoint')
50449             .filter(midpointFilter)
50450             .data(lodash.values(midpoints), function(d) { return d.id; });
50451
50452         groups.exit()
50453             .remove();
50454
50455         var enter = groups.enter()
50456             .insert('g', ':first-child')
50457             .attr('class', 'midpoint');
50458
50459         enter.append('polygon')
50460             .attr('points', '-6,8 10,0 -6,-8')
50461             .attr('class', 'shadow');
50462
50463         enter.append('polygon')
50464             .attr('points', '-3,4 5,0 -3,-4')
50465             .attr('class', 'fill');
50466
50467         groups = groups
50468             .merge(enter)
50469             .attr('transform', function(d) {
50470                 var translate = svgPointTransform(projection),
50471                     a = graph.entity(d.edge[0]),
50472                     b = graph.entity(d.edge[1]),
50473                     angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
50474                 return translate(d) + ' rotate(' + angleVal + ')';
50475             })
50476             .call(svgTagClasses().tags(
50477                 function(d) { return d.parents[0].tags; }
50478             ));
50479
50480         // Propagate data bindings.
50481         groups.select('polygon.shadow');
50482         groups.select('polygon.fill');
50483
50484     };
50485 }
50486
50487 function svgOneWaySegments(projection$$1, graph, dt) {
50488     return function(entity) {
50489         var a,
50490             b,
50491             i = 0,
50492             offset = dt,
50493             segments = [],
50494             clip = identity$5().clipExtent(projection$$1.clipExtent()).stream,
50495             coordinates = graph.childNodes(entity).map(function(n) {
50496                 return n.loc;
50497             });
50498
50499         if (entity.tags.oneway === '-1') coordinates.reverse();
50500
50501         geoStream({
50502             type: 'LineString',
50503             coordinates: coordinates
50504         }, projection$$1.stream(clip({
50505             lineStart: function() {},
50506             lineEnd: function() {
50507                 a = null;
50508             },
50509             point: function(x, y) {
50510                 b = [x, y];
50511
50512                 if (a) {
50513                     var span = geoEuclideanDistance(a, b) - offset;
50514
50515                     if (span >= 0) {
50516                         var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
50517                             dx = dt * Math.cos(angle),
50518                             dy = dt * Math.sin(angle),
50519                             p = [a[0] + offset * Math.cos(angle),
50520                                  a[1] + offset * Math.sin(angle)];
50521
50522                         var segment = 'M' + a[0] + ',' + a[1] +
50523                                       'L' + p[0] + ',' + p[1];
50524
50525                         for (span -= dt; span >= 0; span -= dt) {
50526                             p[0] += dx;
50527                             p[1] += dy;
50528                             segment += 'L' + p[0] + ',' + p[1];
50529                         }
50530
50531                         segment += 'L' + b[0] + ',' + b[1];
50532                         segments.push({id: entity.id, index: i, d: segment});
50533                     }
50534
50535                     offset = -span;
50536                     i++;
50537                 }
50538
50539                 a = b;
50540             }
50541         })));
50542
50543         return segments;
50544     };
50545 }
50546
50547 function svgPath(projection$$1, graph, isArea) {
50548
50549     // Explanation of magic numbers:
50550     // "padding" here allows space for strokes to extend beyond the viewport,
50551     // so that the stroke isn't drawn along the edge of the viewport when
50552     // the shape is clipped.
50553     //
50554     // When drawing lines, pad viewport by 5px.
50555     // When drawing areas, pad viewport by 65px in each direction to allow
50556     // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
50557
50558     var cache = {},
50559         padding = isArea ? 65 : 5,
50560         viewport = projection$$1.clipExtent(),
50561         paddedExtent = [
50562             [viewport[0][0] - padding, viewport[0][1] - padding],
50563             [viewport[1][0] + padding, viewport[1][1] + padding]
50564         ],
50565         clip = identity$5().clipExtent(paddedExtent).stream,
50566         project = projection$$1.stream,
50567         path$$1 = index$4()
50568             .projection({stream: function(output) { return project(clip(output)); }});
50569
50570     return function(entity) {
50571         if (entity.id in cache) {
50572             return cache[entity.id];
50573         } else {
50574             return cache[entity.id] = path$$1(entity.asGeoJSON(graph));
50575         }
50576     };
50577 }
50578
50579 function svgPoints$$1(projection, context) {
50580
50581     function markerPath(selection, klass) {
50582         selection
50583             .attr('class', klass)
50584             .attr('transform', 'translate(-8, -23)')
50585             .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');
50586     }
50587
50588     function sortY(a, b) {
50589         return b.loc[1] - a.loc[1];
50590     }
50591
50592
50593     return function drawPoints(selection, graph, entities, filter) {
50594         var wireframe = context.surface().classed('fill-wireframe'),
50595             points = wireframe ? [] : lodash.filter(entities, function(e) {
50596                 return e.geometry(graph) === 'point';
50597             });
50598
50599         points.sort(sortY);
50600
50601         var layer = selection.selectAll('.layer-hit');
50602
50603         var groups = layer.selectAll('g.point')
50604             .filter(filter)
50605             .data(points, osmEntity$$1.key);
50606
50607         groups.exit()
50608             .remove();
50609
50610         var enter = groups.enter()
50611             .append('g')
50612             .attr('class', function(d) { return 'node point ' + d.id; })
50613             .order();
50614
50615         enter.append('path')
50616             .call(markerPath, 'shadow');
50617
50618         enter.append('ellipse')
50619             .attr('cx', 0.5)
50620             .attr('cy', 1)
50621             .attr('rx', 6.5)
50622             .attr('ry', 3)
50623             .attr('class', 'stroke');
50624
50625         enter.append('path')
50626             .call(markerPath, 'stroke');
50627
50628         enter.append('use')
50629             .attr('transform', 'translate(-5, -19)')
50630             .attr('class', 'icon')
50631             .attr('width', '11px')
50632             .attr('height', '11px');
50633
50634         groups = groups
50635             .merge(enter)
50636             .attr('transform', svgPointTransform(projection))
50637             .call(svgTagClasses());
50638
50639         // Selecting the following implicitly
50640         // sets the data (point entity) on the element
50641         groups.select('.shadow');
50642         groups.select('.stroke');
50643         groups.select('.icon')
50644             .attr('xlink:href', function(entity) {
50645                 var preset = context.presets().match(entity, graph),
50646                     picon = preset && preset.icon;
50647
50648                 if (!picon)
50649                     return '';
50650                 else {
50651                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
50652                     return '#' + picon + (isMaki ? '-11' : '');
50653                 }
50654             });
50655     };
50656 }
50657
50658 function svgRelationMemberTags(graph) {
50659     return function(entity) {
50660         var tags = entity.tags;
50661         graph.parentRelations(entity).forEach(function(relation) {
50662             var type = relation.tags.type;
50663             if (type === 'multipolygon' || type === 'boundary') {
50664                 tags = lodash.extend({}, relation.tags, tags);
50665             }
50666         });
50667         return tags;
50668     };
50669 }
50670
50671 function svgTagClasses() {
50672     var primaries = [
50673             'building', 'highway', 'railway', 'waterway', 'aeroway',
50674             'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
50675             'leisure', 'military', 'place'
50676         ],
50677         statuses = [
50678             'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
50679             'razed', 'demolished', 'obliterated'
50680         ],
50681         secondaries = [
50682             'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
50683             'surface', 'tracktype', 'crossing', 'service', 'sport'
50684         ],
50685         tagClassRe = /^tag-/,
50686         tags = function(entity) { return entity.tags; };
50687
50688
50689     var tagClasses = function(selection$$1) {
50690         selection$$1.each(function tagClassesEach(entity) {
50691             var value = this.className,
50692                 classes, primary, status;
50693
50694             if (value.baseVal !== undefined) value = value.baseVal;
50695
50696             classes = value.trim().split(/\s+/).filter(function(name) {
50697                 return name.length && !tagClassRe.test(name);
50698             }).join(' ');
50699
50700             var t = tags(entity), i, k, v;
50701
50702             // pick at most one primary classification tag..
50703             for (i = 0; i < primaries.length; i++) {
50704                 k = primaries[i];
50705                 v = t[k];
50706                 if (!v || v === 'no') continue;
50707
50708                 primary = k;
50709                 if (statuses.indexOf(v) !== -1) {   // e.g. `railway=abandoned`
50710                     status = v;
50711                     classes += ' tag-' + k;
50712                 } else {
50713                     classes += ' tag-' + k + ' tag-' + k + '-' + v;
50714                 }
50715
50716                 break;
50717             }
50718
50719             // add at most one status tag, only if relates to primary tag..
50720             if (!status) {
50721                 for (i = 0; i < statuses.length; i++) {
50722                     k = statuses[i];
50723                     v = t[k];
50724                     if (!v || v === 'no') continue;
50725
50726                     if (v === 'yes') {   // e.g. `railway=rail + abandoned=yes`
50727                         status = k;
50728                     }
50729                     else if (primary && primary === v) {  // e.g. `railway=rail + abandoned=railway`
50730                         status = k;
50731                     } else if (!primary && primaries.indexOf(v) !== -1) {  // e.g. `abandoned=railway`
50732                         status = k;
50733                         primary = v;
50734                         classes += ' tag-' + v;
50735                     }  // else ignore e.g.  `highway=path + abandoned=railway`
50736
50737                     if (status) break;
50738                 }
50739             }
50740
50741             if (status) {
50742                 classes += ' tag-status tag-status-' + status;
50743             }
50744
50745             // add any secondary (structure) tags
50746             for (i = 0; i < secondaries.length; i++) {
50747                 k = secondaries[i];
50748                 v = t[k];
50749                 if (!v || v === 'no') continue;
50750                 classes += ' tag-' + k + ' tag-' + k + '-' + v;
50751             }
50752
50753             // For highways, look for surface tagging..
50754             if (primary === 'highway') {
50755                 var paved = (t.highway !== 'track');
50756                 for (k in t) {
50757                     v = t[k];
50758                     if (k in osmPavedTags) {
50759                         paved = !!osmPavedTags[k][v];
50760                         break;
50761                     }
50762                 }
50763                 if (!paved) {
50764                     classes += ' tag-unpaved';
50765                 }
50766             }
50767
50768             classes = classes.trim();
50769
50770             if (classes !== value) {
50771                 select(this).attr('class', classes);
50772             }
50773         });
50774     };
50775
50776
50777     tagClasses.tags = function(_) {
50778         if (!arguments.length) return tags;
50779         tags = _;
50780         return tagClasses;
50781     };
50782
50783     return tagClasses;
50784 }
50785
50786 function svgTurns(projection) {
50787
50788     return function drawTurns(selection, graph, turns) {
50789
50790         function key(turn) {
50791             return [turn.from.node + turn.via.node + turn.to.node].join('-');
50792         }
50793
50794         function icon(turn) {
50795             var u = turn.u ? '-u' : '';
50796             if (!turn.restriction)
50797                 return '#turn-yes' + u;
50798             var restriction = graph.entity(turn.restriction).tags.restriction;
50799             return '#turn-' +
50800                 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
50801         }
50802
50803         var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
50804             .data(turns, key);
50805
50806         groups.exit()
50807             .remove();
50808
50809
50810         var enter = groups.enter()
50811             .append('g')
50812             .attr('class', 'turn');
50813
50814         var nEnter = enter
50815             .filter(function (turn) { return !turn.u; });
50816
50817         nEnter.append('rect')
50818             .attr('transform', 'translate(-22, -12)')
50819             .attr('width', '44')
50820             .attr('height', '24');
50821
50822         nEnter.append('use')
50823             .attr('transform', 'translate(-22, -12)')
50824             .attr('width', '44')
50825             .attr('height', '24');
50826
50827
50828         var uEnter = enter
50829             .filter(function (turn) { return turn.u; });
50830
50831         uEnter.append('circle')
50832             .attr('r', '16');
50833
50834         uEnter.append('use')
50835             .attr('transform', 'translate(-16, -16)')
50836             .attr('width', '32')
50837             .attr('height', '32');
50838
50839
50840         groups = groups
50841             .merge(enter);
50842
50843         groups
50844             .attr('transform', function (turn) {
50845                 var v = graph.entity(turn.via.node),
50846                     t = graph.entity(turn.to.node),
50847                     a = geoAngle(v, t, projection),
50848                     p = projection(v.loc),
50849                     r = turn.u ? 0 : 60;
50850
50851                 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
50852                     'rotate(' + a * 180 / Math.PI + ')';
50853             });
50854
50855         groups.select('use')
50856             .attr('xlink:href', icon);
50857
50858         groups.select('rect');
50859         groups.select('circle');
50860
50861         return this;
50862     };
50863 }
50864
50865 function svgVertices$$1(projection$$1, context) {
50866     var radiuses = {
50867         //       z16-, z17, z18+, tagged
50868         shadow: [6,    7.5,   7.5,  11.5],
50869         stroke: [2.5,  3.5,   3.5,  7],
50870         fill:   [1,    1.5,   1.5,  1.5]
50871     };
50872
50873     var hover;
50874
50875
50876     function siblingAndChildVertices(ids, graph, extent$$1) {
50877         var vertices = {};
50878
50879         function addChildVertices(entity) {
50880             if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
50881                 var i;
50882                 if (entity.type === 'way') {
50883                     for (i = 0; i < entity.nodes.length; i++) {
50884                         addChildVertices(graph.entity(entity.nodes[i]));
50885                     }
50886                 } else if (entity.type === 'relation') {
50887                     for (i = 0; i < entity.members.length; i++) {
50888                         var member = context.hasEntity(entity.members[i].id);
50889                         if (member) {
50890                             addChildVertices(member);
50891                         }
50892                     }
50893                 } else if (entity.intersects(extent$$1, graph)) {
50894                     vertices[entity.id] = entity;
50895                 }
50896             }
50897         }
50898
50899         ids.forEach(function(id) {
50900             var entity = context.hasEntity(id);
50901             if (entity && entity.type === 'node') {
50902                 vertices[entity.id] = entity;
50903                 context.graph().parentWays(entity).forEach(function(entity) {
50904                     addChildVertices(entity);
50905                 });
50906             } else if (entity) {
50907                 addChildVertices(entity);
50908             }
50909         });
50910
50911         return vertices;
50912     }
50913
50914
50915     function draw(selection$$1, vertices, klass, graph, zoom$$1, siblings$$1) {
50916
50917         function icon(entity) {
50918             if (entity.id in icons) return icons[entity.id];
50919             icons[entity.id] =
50920                 entity.hasInterestingTags() &&
50921                 context.presets().match(entity, graph).icon;
50922             return icons[entity.id];
50923         }
50924
50925         function setClass(klass) {
50926             return function(entity) {
50927                 this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
50928             };
50929         }
50930
50931         function setAttributes(selection$$1) {
50932             ['shadow','stroke','fill'].forEach(function(klass) {
50933                 var rads = radiuses[klass];
50934                 selection$$1.selectAll('.' + klass)
50935                     .each(function(entity) {
50936                         var i = z && icon(entity),
50937                             c = i ? 0.5 : 0,
50938                             r = rads[i ? 3 : z];
50939
50940                         // slightly increase the size of unconnected endpoints #3775
50941                         if (entity.isEndpoint(graph) && !entity.isConnected(graph)) {
50942                             r += 1.5;
50943                         }
50944
50945                         this.setAttribute('cx', c);
50946                         this.setAttribute('cy', -c);
50947                         this.setAttribute('r', r);
50948                         if (i && klass === 'fill') {
50949                             this.setAttribute('visibility', 'hidden');
50950                         } else {
50951                             this.removeAttribute('visibility');
50952                         }
50953                     });
50954             });
50955
50956             selection$$1.selectAll('use')
50957                 .each(function() {
50958                     if (z) {
50959                         this.removeAttribute('visibility');
50960                     } else {
50961                         this.setAttribute('visibility', 'hidden');
50962                     }
50963                 });
50964         }
50965
50966
50967         siblings$$1 = siblings$$1 || {};
50968
50969         var icons = {},
50970             z = (zoom$$1 < 17 ? 0 : zoom$$1 < 18 ? 1 : 2);
50971
50972         var groups = selection$$1
50973             .data(vertices, osmEntity$$1.key);
50974
50975         groups.exit()
50976             .remove();
50977
50978         var enter = groups.enter()
50979             .append('g')
50980             .attr('class', function(d) { return 'node vertex ' + klass + ' ' + d.id; });
50981
50982         enter.append('circle')
50983             .each(setClass('shadow'));
50984
50985         enter.append('circle')
50986             .each(setClass('stroke'));
50987
50988         // Vertices with icons get a `use`.
50989         enter.filter(function(d) { return icon(d); })
50990             .append('use')
50991             .attr('transform', 'translate(-5, -6)')
50992             .attr('xlink:href', function(d) {
50993                 var picon = icon(d),
50994                     isMaki = dataFeatureIcons.indexOf(picon) !== -1;
50995                 return '#' + picon + (isMaki ? '-11' : '');
50996             })
50997             .attr('width', '11px')
50998             .attr('height', '11px')
50999             .each(setClass('icon'));
51000
51001         // Vertices with tags get a fill.
51002         enter.filter(function(d) { return d.hasInterestingTags(); })
51003             .append('circle')
51004             .each(setClass('fill'));
51005
51006         groups
51007             .merge(enter)
51008             .attr('transform', svgPointTransform(projection$$1))
51009             .classed('sibling', function(entity) { return entity.id in siblings$$1; })
51010             .classed('shared', function(entity) { return graph.isShared(entity); })
51011             .classed('endpoint', function(entity) { return entity.isEndpoint(graph); })
51012             .call(setAttributes);
51013     }
51014
51015
51016     function drawVertices(selection$$1, graph, entities, filter, extent$$1, zoom$$1) {
51017         var siblings$$1 = siblingAndChildVertices(context.selectedIDs(), graph, extent$$1),
51018             wireframe = context.surface().classed('fill-wireframe'),
51019             vertices = [];
51020
51021         for (var i = 0; i < entities.length; i++) {
51022             var entity = entities[i],
51023                 geometry = entity.geometry(graph);
51024
51025             if (wireframe && geometry === 'point') {
51026                 vertices.push(entity);
51027                 continue;
51028             }
51029
51030             if (geometry !== 'vertex')
51031                 continue;
51032
51033             if (entity.id in siblings$$1 ||
51034                 entity.hasInterestingTags() ||
51035                 entity.isEndpoint(graph) ||
51036                 entity.isConnected(graph)) {
51037                 vertices.push(entity);
51038             }
51039         }
51040
51041         var layer = selection$$1.selectAll('.layer-hit');
51042         layer.selectAll('g.vertex.vertex-persistent')
51043             .filter(filter)
51044             .call(draw, vertices, 'vertex-persistent', graph, zoom$$1, siblings$$1);
51045
51046         drawHover(selection$$1, graph, extent$$1, zoom$$1);
51047     }
51048
51049
51050     function drawHover(selection$$1, graph, extent$$1, zoom$$1) {
51051         var hovered = hover ? siblingAndChildVertices([hover.id], graph, extent$$1) : {};
51052         var layer = selection$$1.selectAll('.layer-hit');
51053
51054         layer.selectAll('g.vertex.vertex-hover')
51055             .call(draw, values(hovered), 'vertex-hover', graph, zoom$$1);
51056     }
51057
51058
51059     drawVertices.drawHover = function(selection$$1, graph, target, extent$$1, zoom$$1) {
51060         if (target === hover) return;
51061         hover = target;
51062         drawHover(selection$$1, graph, extent$$1, zoom$$1);
51063     };
51064
51065     return drawVertices;
51066 }
51067
51068 function behaviorEdit(context) {
51069
51070     function edit() {
51071         context.map()
51072             .minzoom(context.minEditableZoom());
51073     }
51074
51075
51076     edit.off = function() {
51077         context.map()
51078             .minzoom(0);
51079     };
51080
51081
51082     return edit;
51083 }
51084
51085 /*
51086    The hover behavior adds the `.hover` class on mouseover to all elements to which
51087    the identical datum is bound, and removes it on mouseout.
51088
51089    The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
51090    representation may consist of several elements scattered throughout the DOM hierarchy.
51091    Only one of these elements can have the :hover pseudo-class, but all of them will
51092    have the .hover class.
51093  */
51094 function behaviorHover(context) {
51095     var dispatch$$1 = dispatch('hover'),
51096         _selection = select(null),
51097         newId = null,
51098         buttonDown,
51099         altDisables,
51100         target;
51101
51102
51103     function keydown() {
51104         if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
51105             _selection.selectAll('.hover')
51106                 .classed('hover-suppressed', true)
51107                 .classed('hover', false);
51108
51109             _selection
51110                 .classed('hover-disabled', true);
51111
51112             dispatch$$1.call('hover', this, null);
51113         }
51114     }
51115
51116
51117     function keyup() {
51118         if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
51119             _selection.selectAll('.hover-suppressed')
51120                 .classed('hover-suppressed', false)
51121                 .classed('hover', true);
51122
51123             _selection
51124                 .classed('hover-disabled', false);
51125
51126             dispatch$$1.call('hover', this, target ? target.id : null);
51127         }
51128     }
51129
51130
51131     var hover = function(selection$$1) {
51132         _selection = selection$$1;
51133         newId = null;
51134
51135         _selection
51136             .on('mouseover.hover', mouseover)
51137             .on('mouseout.hover', mouseout)
51138             .on('mousedown.hover', mousedown);
51139
51140         select(window)
51141             .on('keydown.hover', keydown)
51142             .on('keyup.hover', keyup);
51143
51144
51145         function mouseover() {
51146             if (buttonDown) return;
51147             var target = event.target;
51148             enter(target ? target.__data__ : null);
51149         }
51150
51151
51152         function mouseout() {
51153             if (buttonDown) return;
51154             var target = event.relatedTarget;
51155             enter(target ? target.__data__ : null);
51156         }
51157
51158
51159         function mousedown() {
51160             buttonDown = true;
51161             select(window)
51162                 .on('mouseup.hover', mouseup, true);
51163         }
51164
51165
51166         function mouseup() {
51167             buttonDown = false;
51168             select(window)
51169                 .on('mouseup.hover', null, true);
51170         }
51171
51172
51173         function enter(d) {
51174             if (d === target) return;
51175             target = d;
51176
51177             _selection.selectAll('.hover')
51178                 .classed('hover', false);
51179             _selection.selectAll('.hover-suppressed')
51180                 .classed('hover-suppressed', false);
51181
51182             if (target instanceof osmEntity$$1 && target.id !== newId) {
51183
51184                 // If drawing a way, don't hover on a node that was just placed. #3974
51185                 var mode = context.mode() && context.mode().id;
51186                 if ((mode === 'draw-line' || mode === 'draw-area') && !newId && target.type === 'node') {
51187                     newId = target.id;
51188                     return;
51189                 }
51190
51191                 var selector$$1 = '.' + target.id;
51192
51193                 if (target.type === 'relation') {
51194                     target.members.forEach(function(member) {
51195                         selector$$1 += ', .' + member.id;
51196                     });
51197                 }
51198
51199                 var suppressed = altDisables && event && event.altKey;
51200
51201                 _selection.selectAll(selector$$1)
51202                     .classed(suppressed ? 'hover-suppressed' : 'hover', true);
51203
51204                 dispatch$$1.call('hover', this, !suppressed && target.id);
51205
51206             } else {
51207                 dispatch$$1.call('hover', this, null);
51208             }
51209         }
51210
51211     };
51212
51213
51214     hover.off = function(selection$$1) {
51215         selection$$1.selectAll('.hover')
51216             .classed('hover', false);
51217         selection$$1.selectAll('.hover-suppressed')
51218             .classed('hover-suppressed', false);
51219         selection$$1
51220             .classed('hover-disabled', false);
51221
51222
51223         selection$$1
51224             .on('mouseover.hover', null)
51225             .on('mouseout.hover', null)
51226             .on('mousedown.hover', null);
51227
51228         select(window)
51229             .on('keydown.hover', null)
51230             .on('keyup.hover', null);
51231     };
51232
51233
51234     hover.altDisables = function(_) {
51235         if (!arguments.length) return altDisables;
51236         altDisables = _;
51237         return hover;
51238     };
51239
51240
51241     return utilRebind(hover, dispatch$$1, 'on');
51242 }
51243
51244 function behaviorTail() {
51245     var text$$1,
51246         container,
51247         xmargin = 25,
51248         tooltipSize = [0, 0],
51249         selectionSize = [0, 0];
51250
51251
51252     function tail(selection$$1) {
51253         if (!text$$1) return;
51254
51255         select(window)
51256             .on('resize.tail', function() { selectionSize = utilGetDimensions(selection$$1); });
51257
51258         container = select(document.body)
51259             .append('div')
51260             .style('display', 'none')
51261             .attr('class', 'tail tooltip-inner');
51262
51263         container.append('div')
51264             .text(text$$1);
51265
51266         selection$$1
51267             .on('mousemove.tail', mousemove)
51268             .on('mouseenter.tail', mouseenter)
51269             .on('mouseleave.tail', mouseleave);
51270
51271         container
51272             .on('mousemove.tail', mousemove);
51273
51274         tooltipSize = utilGetDimensions(container);
51275         selectionSize = utilGetDimensions(selection$$1);
51276
51277
51278         function show() {
51279             container.style('display', 'block');
51280             tooltipSize = utilGetDimensions(container);
51281         }
51282
51283
51284         function mousemove() {
51285             if (container.style('display') === 'none') show();
51286             var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
51287                 -tooltipSize[0] - xmargin : xmargin;
51288             container.classed('left', xoffset > 0);
51289             utilSetTransform(container, event.clientX + xoffset, event.clientY);
51290         }
51291
51292
51293         function mouseleave() {
51294             if (event.relatedTarget !== container.node()) {
51295                 container.style('display', 'none');
51296             }
51297         }
51298
51299
51300         function mouseenter() {
51301             if (event.relatedTarget !== container.node()) {
51302                 show();
51303             }
51304         }
51305     }
51306
51307
51308     tail.off = function(selection$$1) {
51309         if (!text$$1) return;
51310
51311         container
51312             .on('mousemove.tail', null)
51313             .remove();
51314
51315         selection$$1
51316             .on('mousemove.tail', null)
51317             .on('mouseenter.tail', null)
51318             .on('mouseleave.tail', null);
51319
51320         select(window)
51321             .on('resize.tail', null);
51322     };
51323
51324
51325     tail.text = function(_) {
51326         if (!arguments.length) return text$$1;
51327         text$$1 = _;
51328         return tail;
51329     };
51330
51331
51332     return tail;
51333 }
51334
51335 var usedTails = {};
51336 var disableSpace = false;
51337 var lastSpace = null;
51338
51339
51340 function behaviorDraw(context) {
51341     var dispatch$$1 = dispatch('move', 'click', 'clickWay',
51342             'clickNode', 'undo', 'cancel', 'finish'),
51343         keybinding = d3keybinding('draw'),
51344         hover = behaviorHover(context)
51345             .altDisables(true)
51346             .on('hover', context.ui().sidebar.hover),
51347         tail = behaviorTail(),
51348         edit = behaviorEdit(context),
51349         closeTolerance = 4,
51350         tolerance = 12,
51351         mouseLeave = false,
51352         lastMouse = null;
51353
51354
51355     function datum() {
51356         if (event.altKey) return {};
51357
51358         if (event.type === 'keydown') {
51359             return (lastMouse && lastMouse.target.__data__) || {};
51360         } else {
51361             return event.target.__data__ || {};
51362         }
51363     }
51364
51365
51366     function mousedown() {
51367
51368         function point() {
51369             var p = context.container().node();
51370             return touchId !== null ? touches(p).filter(function(p) {
51371                 return p.identifier === touchId;
51372             })[0] : mouse(p);
51373         }
51374
51375         var element = select(this),
51376             touchId = event.touches ? event.changedTouches[0].identifier : null,
51377             t1 = +new Date(),
51378             p1 = point();
51379
51380         element.on('mousemove.draw', null);
51381
51382         select(window).on('mouseup.draw', function() {
51383             var t2 = +new Date(),
51384                 p2 = point(),
51385                 dist = geoEuclideanDistance(p1, p2);
51386
51387             element.on('mousemove.draw', mousemove);
51388             select(window).on('mouseup.draw', null);
51389
51390             if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
51391                 // Prevent a quick second click
51392                 select(window).on('click.draw-block', function() {
51393                     event.stopPropagation();
51394                 }, true);
51395
51396                 context.map().dblclickEnable(false);
51397
51398                 window.setTimeout(function() {
51399                     context.map().dblclickEnable(true);
51400                     select(window).on('click.draw-block', null);
51401                 }, 500);
51402
51403                 click();
51404             }
51405         }, true);
51406     }
51407
51408
51409     function mousemove() {
51410         lastMouse = event;
51411         dispatch$$1.call('move', this, datum());
51412     }
51413
51414
51415     function mouseenter() {
51416         mouseLeave = false;
51417     }
51418
51419
51420     function mouseleave() {
51421         mouseLeave = true;
51422     }
51423
51424
51425     function click() {
51426         var d = datum();
51427         if (d.type === 'way') {
51428             var dims = context.map().dimensions(),
51429                 mouse$$1 = context.mouse(),
51430                 pad = 5,
51431                 trySnap = mouse$$1[0] > pad && mouse$$1[0] < dims[0] - pad &&
51432                     mouse$$1[1] > pad && mouse$$1[1] < dims[1] - pad;
51433
51434             if (trySnap) {
51435                 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection),
51436                     edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
51437                 dispatch$$1.call('clickWay', this, choice.loc, edge);
51438             } else {
51439                 dispatch$$1.call('click', this, context.map().mouseCoordinates());
51440             }
51441
51442         } else if (d.type === 'node') {
51443             dispatch$$1.call('clickNode', this, d);
51444
51445         } else {
51446             dispatch$$1.call('click', this, context.map().mouseCoordinates());
51447         }
51448     }
51449
51450
51451     function space() {
51452         event.preventDefault();
51453         event.stopPropagation();
51454
51455         var currSpace = context.mouse();
51456         if (disableSpace && lastSpace) {
51457             var dist = geoEuclideanDistance(lastSpace, currSpace);
51458             if (dist > tolerance) {
51459                 disableSpace = false;
51460             }
51461         }
51462
51463         if (disableSpace || mouseLeave || !lastMouse) return;
51464
51465         // user must move mouse or release space bar to allow another click
51466         lastSpace = currSpace;
51467         disableSpace = true;
51468
51469         select(window).on('keyup.space-block', function() {
51470             event.preventDefault();
51471             event.stopPropagation();
51472             disableSpace = false;
51473             select(window).on('keyup.space-block', null);
51474         });
51475
51476         click();
51477     }
51478
51479
51480     function backspace() {
51481         event.preventDefault();
51482         dispatch$$1.call('undo');
51483     }
51484
51485
51486     function del() {
51487         event.preventDefault();
51488         dispatch$$1.call('cancel');
51489     }
51490
51491
51492     function ret() {
51493         event.preventDefault();
51494         dispatch$$1.call('finish');
51495     }
51496
51497
51498     function draw(selection$$1) {
51499         context.install(hover);
51500         context.install(edit);
51501
51502         if (!context.inIntro() && !usedTails[tail.text()]) {
51503             context.install(tail);
51504         }
51505
51506         keybinding
51507             .on('⌫', backspace)
51508             .on('⌦', del)
51509             .on('⎋', ret)
51510             .on('↩', ret)
51511             .on('space', space)
51512             .on('⌥space', space);
51513
51514         selection$$1
51515             .on('mouseenter.draw', mouseenter)
51516             .on('mouseleave.draw', mouseleave)
51517             .on('mousedown.draw', mousedown)
51518             .on('mousemove.draw', mousemove);
51519
51520         select(document)
51521             .call(keybinding);
51522
51523         return draw;
51524     }
51525
51526
51527     draw.off = function(selection$$1) {
51528         context.ui().sidebar.hover.cancel();
51529         context.uninstall(hover);
51530         context.uninstall(edit);
51531
51532         if (!context.inIntro() && !usedTails[tail.text()]) {
51533             context.uninstall(tail);
51534             usedTails[tail.text()] = true;
51535         }
51536
51537         selection$$1
51538             .on('mouseenter.draw', null)
51539             .on('mouseleave.draw', null)
51540             .on('mousedown.draw', null)
51541             .on('mousemove.draw', null);
51542
51543         select(window)
51544             .on('mouseup.draw', null);
51545             // note: keyup.space-block, click.draw-block should remain
51546
51547         select(document)
51548             .call(keybinding.off);
51549     };
51550
51551
51552     draw.tail = function(_) {
51553         tail.text(_);
51554         return draw;
51555     };
51556
51557
51558     return utilRebind(draw, dispatch$$1, 'on');
51559 }
51560
51561 function behaviorAddWay(context) {
51562     var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
51563         draw = behaviorDraw(context);
51564
51565     var addWay = function(surface) {
51566         draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
51567             .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
51568             .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
51569             .on('cancel', addWay.cancel)
51570             .on('finish', addWay.cancel);
51571
51572         context.map()
51573             .dblclickEnable(false);
51574
51575         surface.call(draw);
51576     };
51577
51578
51579     addWay.off = function(surface) {
51580         surface.call(draw.off);
51581     };
51582
51583
51584     addWay.cancel = function() {
51585         window.setTimeout(function() {
51586             context.map().dblclickEnable(true);
51587         }, 1000);
51588
51589         context.enter(modeBrowse(context));
51590     };
51591
51592
51593     addWay.tail = function(text$$1) {
51594         draw.tail(text$$1);
51595         return addWay;
51596     };
51597
51598
51599     return utilRebind(addWay, dispatch$$1, 'on');
51600 }
51601
51602 function behaviorBreathe() {
51603     var duration = 800,
51604         steps = 4,
51605         selector$$1 = '.selected.shadow, .selected .shadow',
51606         selected = select(null),
51607         classed = '',
51608         params = {},
51609         done = false,
51610         timer$$1;
51611
51612
51613     function ratchetyInterpolator(a, b, steps, units) {
51614         a = parseFloat(a);
51615         b = parseFloat(b);
51616         var sample = quantize$1()
51617             .domain([0, 1])
51618             .range(quantize(reinterpolate(a, b), steps));
51619
51620         return function(t) {
51621             return String(sample(t)) + (units || '');
51622         };
51623     }
51624
51625
51626     function reset(selection$$1) {
51627         selection$$1
51628             .style('stroke-opacity', null)
51629             .style('stroke-width', null)
51630             .style('fill-opacity', null)
51631             .style('r', null);
51632     }
51633
51634
51635     function setAnimationParams(transition$$1, fromTo) {
51636         var toFrom = (fromTo === 'from' ? 'to' : 'from');
51637
51638         transition$$1
51639             .styleTween('stroke-opacity', function(d) {
51640                 return ratchetyInterpolator(
51641                     params[d.id][toFrom].opacity,
51642                     params[d.id][fromTo].opacity,
51643                     steps
51644                 );
51645             })
51646             .styleTween('stroke-width', function(d) {
51647                 return ratchetyInterpolator(
51648                     params[d.id][toFrom].width,
51649                     params[d.id][fromTo].width,
51650                     steps,
51651                     'px'
51652                 );
51653             })
51654             .styleTween('fill-opacity', function(d) {
51655                 return ratchetyInterpolator(
51656                     params[d.id][toFrom].opacity,
51657                     params[d.id][fromTo].opacity,
51658                     steps
51659                 );
51660             })
51661             .styleTween('r', function(d) {
51662                 return ratchetyInterpolator(
51663                     params[d.id][toFrom].width,
51664                     params[d.id][fromTo].width,
51665                     steps,
51666                     'px'
51667                 );
51668             });
51669     }
51670
51671
51672     function calcAnimationParams(selection$$1) {
51673         selection$$1
51674             .call(reset)
51675             .each(function(d) {
51676                 var s = select(this),
51677                     tag = s.node().tagName,
51678                     p = {'from': {}, 'to': {}},
51679                     opacity, width;
51680
51681                 // determine base opacity and width
51682                 if (tag === 'circle') {
51683                     opacity = parseFloat(s.style('fill-opacity') || 0.5);
51684                     width = parseFloat(s.style('r') || 15.5);
51685                 } else {
51686                     opacity = parseFloat(s.style('stroke-opacity') || 0.7);
51687                     width = parseFloat(s.style('stroke-width') || 10);
51688                 }
51689
51690                 // calculate from/to interpolation params..
51691                 p.tag = tag;
51692                 p.from.opacity = opacity * 0.6;
51693                 p.to.opacity = opacity * 1.25;
51694                 p.from.width = width * 0.7;
51695                 p.to.width = width * (tag === 'circle' ? 1.5 : 1);
51696                 params[d.id] = p;
51697             });
51698     }
51699
51700
51701     function run(surface, fromTo) {
51702         var toFrom = (fromTo === 'from' ? 'to' : 'from'),
51703             currSelected = surface.selectAll(selector$$1),
51704             currClassed = surface.attr('class');
51705
51706         if (done || currSelected.empty()) {
51707             selected.call(reset);
51708             return;
51709         }
51710
51711         if (!lodash.isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
51712             selected.call(reset);
51713             classed = currClassed;
51714             selected = currSelected.call(calcAnimationParams);
51715         }
51716
51717         selected
51718             .transition()
51719             .duration(duration)
51720             .call(setAnimationParams, fromTo)
51721             .on('end', function() {
51722                 surface.call(run, toFrom);
51723             });
51724     }
51725
51726
51727     var breathe = function(surface) {
51728         done = false;
51729         timer$$1 = timer(function() {
51730             // wait for elements to actually become selected
51731             if (surface.selectAll(selector$$1).empty()) {
51732                 return false;
51733             }
51734
51735             surface.call(run, 'from');
51736             timer$$1.stop();
51737             return true;
51738         }, 20);
51739     };
51740
51741
51742     breathe.off = function() {
51743         done = true;
51744         if (timer$$1) {
51745             timer$$1.stop();
51746         }
51747         selected
51748             .interrupt()
51749             .call(reset);
51750     };
51751
51752
51753     return breathe;
51754 }
51755
51756 function behaviorCopy(context) {
51757     var keybinding = d3keybinding('copy');
51758
51759
51760     function groupEntities(ids, graph) {
51761         var entities = ids.map(function (id) { return graph.entity(id); });
51762         return lodash.extend({relation: [], way: [], node: []},
51763             lodash.groupBy(entities, function(entity) { return entity.type; }));
51764     }
51765
51766
51767     function getDescendants(id, graph, descendants) {
51768         var entity = graph.entity(id),
51769             i, children;
51770
51771         descendants = descendants || {};
51772
51773         if (entity.type === 'relation') {
51774             children = lodash.map(entity.members, 'id');
51775         } else if (entity.type === 'way') {
51776             children = entity.nodes;
51777         } else {
51778             children = [];
51779         }
51780
51781         for (i = 0; i < children.length; i++) {
51782             if (!descendants[children[i]]) {
51783                 descendants[children[i]] = true;
51784                 descendants = getDescendants(children[i], graph, descendants);
51785             }
51786         }
51787
51788         return descendants;
51789     }
51790
51791
51792     function doCopy() {
51793         event.preventDefault();
51794
51795         var graph = context.graph(),
51796             selected = groupEntities(context.selectedIDs(), graph),
51797             canCopy = [],
51798             skip = {},
51799             i, entity;
51800
51801         for (i = 0; i < selected.relation.length; i++) {
51802             entity = selected.relation[i];
51803             if (!skip[entity.id] && entity.isComplete(graph)) {
51804                 canCopy.push(entity.id);
51805                 skip = getDescendants(entity.id, graph, skip);
51806             }
51807         }
51808         for (i = 0; i < selected.way.length; i++) {
51809             entity = selected.way[i];
51810             if (!skip[entity.id]) {
51811                 canCopy.push(entity.id);
51812                 skip = getDescendants(entity.id, graph, skip);
51813             }
51814         }
51815         for (i = 0; i < selected.node.length; i++) {
51816             entity = selected.node[i];
51817             if (!skip[entity.id]) {
51818                 canCopy.push(entity.id);
51819             }
51820         }
51821
51822         context.copyIDs(canCopy);
51823     }
51824
51825
51826     function copy() {
51827         keybinding.on(uiCmd('⌘C'), doCopy);
51828         select(document).call(keybinding);
51829         return copy;
51830     }
51831
51832
51833     copy.off = function() {
51834         select(document).call(keybinding.off);
51835     };
51836
51837
51838     return copy;
51839 }
51840
51841 /*
51842     `behaviorDrag` is like `d3.behavior.drag`, with the following differences:
51843
51844     * The `origin` function is expected to return an [x, y] tuple rather than an
51845       {x, y} object.
51846     * The events are `start`, `move`, and `end`.
51847       (https://github.com/mbostock/d3/issues/563)
51848     * The `start` event is not dispatched until the first cursor movement occurs.
51849       (https://github.com/mbostock/d3/pull/368)
51850     * The `move` event has a `point` and `delta` [x, y] tuple properties rather
51851       than `x`, `y`, `dx`, and `dy` properties.
51852     * The `end` event is not dispatched if no movement occurs.
51853     * An `off` function is available that unbinds the drag's internal event handlers.
51854  */
51855
51856 function behaviorDrag() {
51857     var event$$1 = dispatch('start', 'move', 'end'),
51858         origin = null,
51859         selector$$1 = '',
51860         filter = null,
51861         event_, target, surface;
51862
51863
51864     var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'),
51865         d3_event_userSelectSuppress = function() {
51866             var selection$$1 = selection(),
51867                 select$$1 = selection$$1.style(d3_event_userSelectProperty);
51868             selection$$1.style(d3_event_userSelectProperty, 'none');
51869             return function() {
51870                 selection$$1.style(d3_event_userSelectProperty, select$$1);
51871             };
51872         };
51873
51874
51875     function d3_eventCancel() {
51876         event.stopPropagation();
51877         event.preventDefault();
51878     }
51879
51880
51881     function eventOf(thiz, argumentz) {
51882         return function(e1) {
51883             e1.target = drag$$1;
51884             customEvent(e1, event$$1.apply, event$$1, [e1.type, thiz, argumentz]);
51885         };
51886     }
51887
51888
51889     function dragstart() {
51890         target = this;
51891         event_ = eventOf(target, arguments);
51892
51893         var eventTarget = event.target,
51894             touchId = event.touches ? event.changedTouches[0].identifier : null,
51895             offset,
51896             origin_ = point(),
51897             started = false,
51898             selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
51899
51900         select(window)
51901             .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
51902             .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
51903
51904         if (origin) {
51905             offset = origin.apply(target, arguments);
51906             offset = [offset[0] - origin_[0], offset[1] - origin_[1]];
51907         } else {
51908             offset = [0, 0];
51909         }
51910
51911         if (touchId === null) {
51912             event.stopPropagation();
51913         }
51914
51915
51916         function point() {
51917             var p = surface || target.parentNode;
51918             return touchId !== null ? touches(p).filter(function(p) {
51919                 return p.identifier === touchId;
51920             })[0] : mouse(p);
51921         }
51922
51923
51924         function dragmove() {
51925             var p = point(),
51926                 dx = p[0] - origin_[0],
51927                 dy = p[1] - origin_[1];
51928
51929             if (dx === 0 && dy === 0)
51930                 return;
51931
51932             if (!started) {
51933                 started = true;
51934                 event_({ type: 'start' });
51935             }
51936
51937             origin_ = p;
51938             d3_eventCancel();
51939
51940             event_({
51941                 type: 'move',
51942                 point: [p[0] + offset[0],  p[1] + offset[1]],
51943                 delta: [dx, dy]
51944             });
51945         }
51946
51947
51948         function dragend() {
51949             if (started) {
51950                 event_({ type: 'end' });
51951
51952                 d3_eventCancel();
51953                 if (event.target === eventTarget) {
51954                     select(window)
51955                         .on('click.drag', click, true);
51956                 }
51957             }
51958
51959             select(window)
51960                 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
51961                 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
51962
51963             selectEnable();
51964         }
51965
51966
51967         function click() {
51968             d3_eventCancel();
51969             select(window)
51970                 .on('click.drag', null);
51971         }
51972     }
51973
51974
51975     function drag$$1(selection$$1) {
51976         var matchesSelector = utilPrefixDOMProperty('matchesSelector'),
51977             delegate = dragstart;
51978
51979         if (selector$$1) {
51980             delegate = function() {
51981                 var root = this,
51982                     target = event.target;
51983                 for (; target && target !== root; target = target.parentNode) {
51984                     if (target[matchesSelector](selector$$1) &&
51985                             (!filter || filter(target.__data__))) {
51986                         return dragstart.call(target, target.__data__);
51987                     }
51988                 }
51989             };
51990         }
51991
51992         selection$$1
51993             .on('mousedown.drag' + selector$$1, delegate)
51994             .on('touchstart.drag' + selector$$1, delegate);
51995     }
51996
51997
51998     drag$$1.off = function(selection$$1) {
51999         selection$$1
52000             .on('mousedown.drag' + selector$$1, null)
52001             .on('touchstart.drag' + selector$$1, null);
52002     };
52003
52004
52005     drag$$1.selector = function(_) {
52006         if (!arguments.length) return selector$$1;
52007         selector$$1 = _;
52008         return drag$$1;
52009     };
52010
52011
52012     drag$$1.filter = function(_) {
52013         if (!arguments.length) return origin;
52014         filter = _;
52015         return drag$$1;
52016     };
52017
52018
52019     drag$$1.origin = function (_) {
52020         if (!arguments.length) return origin;
52021         origin = _;
52022         return drag$$1;
52023     };
52024
52025
52026     drag$$1.cancel = function() {
52027         select(window)
52028             .on('mousemove.drag', null)
52029             .on('mouseup.drag', null);
52030         return drag$$1;
52031     };
52032
52033
52034     drag$$1.target = function() {
52035         if (!arguments.length) return target;
52036         target = arguments[0];
52037         event_ = eventOf(target, Array.prototype.slice.call(arguments, 1));
52038         return drag$$1;
52039     };
52040
52041
52042     drag$$1.surface = function() {
52043         if (!arguments.length) return surface;
52044         surface = arguments[0];
52045         return drag$$1;
52046     };
52047
52048
52049     return utilRebind(drag$$1, event$$1, 'on');
52050 }
52051
52052 function behaviorDrawWay(context, wayId, index, mode, startGraph) {
52053
52054     var origWay = context.entity(wayId),
52055         isArea = context.geometry(wayId) === 'area',
52056         tempEdits = 0,
52057         annotation = t((origWay.isDegenerate() ?
52058             'operations.start.annotation.' :
52059             'operations.continue.annotation.') + context.geometry(wayId)),
52060         draw = behaviorDraw(context),
52061         startIndex,
52062         start,
52063         end,
52064         segment;
52065
52066
52067     // initialize the temporary drawing entities
52068     if (!isArea) {
52069         startIndex = typeof index === 'undefined' ? origWay.nodes.length - 1 : 0;
52070         start = osmNode({ id: 'nStart', loc: context.entity(origWay.nodes[startIndex]).loc });
52071         end = osmNode({ id: 'nEnd', loc: context.map().mouseCoordinates() });
52072         segment = osmWay({ id: 'wTemp',
52073             nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
52074             tags: lodash.clone(origWay.tags)
52075         });
52076     } else {
52077         end = osmNode({ loc: context.map().mouseCoordinates() });
52078     }
52079
52080     // Push an annotated state for undo to return back to.
52081     // We must make sure to remove this edit later.
52082     context.perform(actionNoop(), annotation);
52083     tempEdits++;
52084
52085     // Add the temporary drawing entities to the graph.
52086     // We must make sure to remove this edit later.
52087     context.perform(AddDrawEntities());
52088     tempEdits++;
52089
52090
52091     function move(datum) {
52092         var loc;
52093
52094         if (datum.type === 'node' && datum.id !== end.id) {
52095             loc = datum.loc;
52096
52097         } else if (datum.type === 'way') {
52098             var dims = context.map().dimensions(),
52099                 mouse = context.mouse(),
52100                 pad = 5,
52101                 trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
52102                     mouse[1] > pad && mouse[1] < dims[1] - pad;
52103
52104             if (trySnap) {
52105                 loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
52106             }
52107         }
52108
52109         if (!loc) {
52110             loc = context.map().mouseCoordinates();
52111         }
52112
52113         context.replace(actionMoveNode(end.id, loc));
52114         end = context.entity(end.id);
52115     }
52116
52117
52118     function undone() {
52119         // Undo popped the history back to the initial annotated no-op edit.
52120         // Remove initial no-op edit and whatever edit happened immediately before it.
52121         context.pop(2);
52122         tempEdits = 0;
52123
52124         if (context.hasEntity(wayId)) {
52125             context.enter(mode);
52126         } else {
52127             context.enter(modeBrowse(context));
52128         }
52129     }
52130
52131
52132     function setActiveElements() {
52133         var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
52134         context.surface().selectAll(utilEntitySelector(active))
52135             .classed('active', true);
52136     }
52137
52138
52139     var drawWay = function(surface) {
52140         draw.on('move', move)
52141             .on('click', drawWay.add)
52142             .on('clickWay', drawWay.addWay)
52143             .on('clickNode', drawWay.addNode)
52144             .on('undo', context.undo)
52145             .on('cancel', drawWay.cancel)
52146             .on('finish', drawWay.finish);
52147
52148         context.map()
52149             .dblclickEnable(false)
52150             .on('drawn.draw', setActiveElements);
52151
52152         setActiveElements();
52153
52154         surface.call(draw);
52155
52156         context.history()
52157             .on('undone.draw', undone);
52158     };
52159
52160
52161     drawWay.off = function(surface) {
52162         // Drawing was interrupted unexpectedly.
52163         // This can happen if the user changes modes,
52164         // clicks geolocate button, a hashchange event occurs, etc.
52165         if (tempEdits) {
52166             context.pop(tempEdits);
52167             while (context.graph() !== startGraph) {
52168                 context.pop();
52169             }
52170         }
52171
52172         context.map()
52173             .on('drawn.draw', null);
52174
52175         surface.call(draw.off)
52176             .selectAll('.active')
52177             .classed('active', false);
52178
52179         context.history()
52180             .on('undone.draw', null);
52181     };
52182
52183
52184     function AddDrawEntities() {
52185         return function(graph) {
52186             if (isArea) {
52187                 // For area drawing, there is no need for a temporary node.
52188                 // `end` gets inserted into the way as the penultimate node.
52189                 return graph
52190                     .replace(end)
52191                     .replace(origWay.addNode(end.id));
52192             } else {
52193                 // For line drawing, add a temporary start, end, and segment to the graph.
52194                 // This allows us to class the new segment as `active`, but still
52195                 // connect it back to parts of the way that have already been drawn.
52196                 return graph
52197                     .replace(start)
52198                     .replace(end)
52199                     .replace(segment);
52200             }
52201         };
52202     }
52203
52204
52205     function ReplaceDrawEntities(newNode) {
52206         return function(graph) {
52207             if (isArea) {
52208                 // For area drawing, we didn't create a temporary node.
52209                 // `newNode` gets inserted into the _original_ way as the penultimate node.
52210                 return graph
52211                     .replace(origWay.addNode(newNode.id))
52212                     .remove(end);
52213             } else {
52214                 // For line drawing, add the `newNode` to the way at specified index,
52215                 // and remove the temporary start, end, and segment.
52216                 return graph
52217                     .replace(origWay.addNode(newNode.id, index))
52218                     .remove(end)
52219                     .remove(segment)
52220                     .remove(start);
52221             }
52222         };
52223     }
52224
52225
52226     // Accept the current position of the temporary node and continue drawing.
52227     drawWay.add = function(loc) {
52228         // prevent duplicate nodes
52229         var last = context.hasEntity(origWay.nodes[origWay.nodes.length - (isArea ? 2 : 1)]);
52230         if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
52231
52232         context.pop(tempEdits);
52233
52234         if (isArea) {
52235             context.perform(
52236                 AddDrawEntities(),
52237                 annotation
52238             );
52239         } else {
52240             var newNode = osmNode({loc: loc});
52241             context.perform(
52242                 actionAddEntity(newNode),
52243                 ReplaceDrawEntities(newNode),
52244                 annotation
52245             );
52246         }
52247
52248         tempEdits = 0;
52249         context.enter(mode);
52250     };
52251
52252
52253     // Connect the way to an existing way.
52254     drawWay.addWay = function(loc, edge) {
52255         if (isArea) {
52256             context.pop(tempEdits);
52257
52258             context.perform(
52259                 AddDrawEntities(),
52260                 actionAddMidpoint({ loc: loc, edge: edge}, end),
52261                 annotation
52262             );
52263         } else {
52264             var previousEdge = startIndex ?
52265                 [origWay.nodes[startIndex], origWay.nodes[startIndex - 1]] :
52266                 [origWay.nodes[0], origWay.nodes[1]];
52267
52268             // Avoid creating duplicate segments
52269             if (geoEdgeEqual(edge, previousEdge))
52270                 return;
52271
52272             context.pop(tempEdits);
52273
52274             var newNode = osmNode({ loc: loc });
52275             context.perform(
52276                 actionAddMidpoint({ loc: loc, edge: edge}, newNode),
52277                 ReplaceDrawEntities(newNode),
52278                 annotation
52279             );
52280         }
52281
52282         tempEdits = 0;
52283         context.enter(mode);
52284     };
52285
52286
52287     // Connect the way to an existing node and continue drawing.
52288     drawWay.addNode = function(node) {
52289         // Avoid creating duplicate segments
52290         if (origWay.areAdjacent(node.id, origWay.nodes[origWay.nodes.length - 1])) return;
52291
52292         // Clicks should not occur on the drawing node, however a space keypress can
52293         // sometimes grab that node's datum (before it gets classed as `active`?)  #4016
52294         if (node.id === end.id) {
52295             drawWay.add(node.loc);
52296             return;
52297         }
52298
52299         context.pop(tempEdits);
52300
52301         context.perform(
52302             ReplaceDrawEntities(node),
52303             annotation
52304         );
52305
52306         tempEdits = 0;
52307         context.enter(mode);
52308     };
52309
52310
52311     // Finish the draw operation, removing the temporary edits.
52312     // If the way has enough nodes to be valid, it's selected.
52313     // Otherwise, delete everything and return to browse mode.
52314     drawWay.finish = function() {
52315         context.pop(tempEdits);
52316         tempEdits = 0;
52317
52318         var way = context.hasEntity(wayId);
52319         if (!way || way.isDegenerate()) {
52320             drawWay.cancel();
52321             return;
52322         }
52323
52324         window.setTimeout(function() {
52325             context.map().dblclickEnable(true);
52326         }, 1000);
52327
52328         context.enter(modeSelect(context, [wayId]).newFeature(true));
52329     };
52330
52331
52332     // Cancel the draw operation, delete everything, and return to browse mode.
52333     drawWay.cancel = function() {
52334         context.pop(tempEdits);
52335         tempEdits = 0;
52336
52337         while (context.graph() !== startGraph) {
52338             context.pop();
52339         }
52340
52341         window.setTimeout(function() {
52342             context.map().dblclickEnable(true);
52343         }, 1000);
52344
52345         context.enter(modeBrowse(context));
52346     };
52347
52348
52349     drawWay.tail = function(text) {
52350         draw.tail(text);
52351         return drawWay;
52352     };
52353
52354
52355     return drawWay;
52356 }
52357
52358 function behaviorHash(context) {
52359     var s0 = null, // cached window.location.hash
52360         lat = 90 - 1e-8; // allowable latitude range
52361
52362
52363     var parser = function(map, s) {
52364         var q = utilStringQs(s);
52365         var args = (q.map || '').split('/').map(Number);
52366
52367         if (args.length < 3 || args.some(isNaN)) {
52368             return true; // replace bogus hash
52369
52370         } else if (s !== formatter(map).slice(1)) {   // hash has changed
52371             var mode = context.mode(),
52372                 dist = geoSphericalDistance(map.center(), [args[2], args[1]]),
52373                 maxdist = 500;
52374
52375             // Don't allow the hash location to change too much while drawing
52376             // This can happen if the user accidently hit the back button.  #3996
52377             if (mode && mode.id.match(/^draw/) !== null && dist > maxdist) {
52378                 context.enter(modeBrowse(context));
52379             }
52380
52381             map.centerZoom([args[2], Math.min(lat, Math.max(-lat, args[1]))], args[0]);
52382         }
52383     };
52384
52385
52386     var formatter = function(map) {
52387         var center = map.center(),
52388             zoom$$1 = map.zoom(),
52389             precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2)),
52390             q = lodash.omit(utilStringQs(window.location.hash.substring(1)),
52391                 ['comment', 'hashtags', 'walkthrough']
52392             ),
52393             newParams = {};
52394
52395         delete q.id;
52396         var selected = context.selectedIDs().filter(function(id) {
52397             return !context.entity(id).isNew();
52398         });
52399         if (selected.length) {
52400             newParams.id = selected.join(',');
52401         }
52402
52403         newParams.map = zoom$$1.toFixed(2) +
52404             '/' + center[1].toFixed(precision) +
52405             '/' + center[0].toFixed(precision);
52406
52407         return '#' + utilQsString(lodash.assign(q, newParams), true);
52408     };
52409
52410
52411     function update() {
52412         if (context.inIntro()) return;
52413         var s1 = formatter(context.map());
52414         if (s0 !== s1) {
52415             window.location.replace(s0 = s1);  // don't recenter the map!
52416         }
52417     }
52418
52419
52420     var throttledUpdate = lodash.throttle(update, 500);
52421
52422
52423     function hashchange() {
52424         if (window.location.hash === s0) return;  // ignore spurious hashchange events
52425         if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
52426             update(); // replace bogus hash
52427         }
52428     }
52429
52430
52431     function hash() {
52432         context.map()
52433             .on('move.hash', throttledUpdate);
52434
52435         context
52436             .on('enter.hash', throttledUpdate);
52437
52438         select(window)
52439             .on('hashchange.hash', hashchange);
52440
52441         if (window.location.hash) {
52442
52443             var q = utilStringQs(window.location.hash.substring(1));
52444
52445             if (q.id) {
52446                 context.zoomToEntity(q.id.split(',')[0], !q.map);
52447             }
52448
52449             if (q.comment) {
52450                 context.storage('comment', q.comment);
52451                 context.storage('commentDate', Date.now());
52452             }
52453
52454             if (q.hashtags) {
52455                 context.storage('hashtags', q.hashtags);
52456             }
52457
52458             if (q.walkthrough === 'true') {
52459                 hash.startWalkthrough = true;
52460             }
52461
52462             hashchange();
52463
52464             if (q.map) {
52465                 hash.hadHash = true;
52466             }
52467         }
52468     }
52469
52470
52471     hash.off = function() {
52472         throttledUpdate.cancel();
52473
52474         context.map()
52475             .on('move.hash', null);
52476
52477         context
52478             .on('enter.hash', null);
52479
52480         select(window)
52481             .on('hashchange.hash', null);
52482
52483         window.location.hash = '';
52484     };
52485
52486
52487     return hash;
52488 }
52489
52490 function behaviorLasso(context) {
52491
52492     var behavior = function(selection$$1) {
52493         var lasso;
52494
52495
52496         function mousedown() {
52497             var button = 0;  // left
52498             if (event.button === button && event.shiftKey === true) {
52499                 lasso = null;
52500
52501                 select(window)
52502                     .on('mousemove.lasso', mousemove)
52503                     .on('mouseup.lasso', mouseup);
52504
52505                 event.stopPropagation();
52506             }
52507         }
52508
52509
52510         function mousemove() {
52511             if (!lasso) {
52512                 lasso = uiLasso(context);
52513                 context.surface().call(lasso);
52514             }
52515
52516             lasso.p(context.mouse());
52517         }
52518
52519
52520         function normalize(a, b) {
52521             return [
52522                 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
52523                 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
52524         }
52525
52526
52527         function lassoed() {
52528             if (!lasso) return [];
52529
52530             var graph = context.graph(),
52531                 bounds$$1 = lasso.extent().map(context.projection.invert),
52532                 extent$$1 = geoExtent$$1(normalize(bounds$$1[0], bounds$$1[1]));
52533
52534             return lodash.map(context.intersects(extent$$1).filter(function(entity) {
52535                 return entity.type === 'node' &&
52536                     geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
52537                     !context.features().isHidden(entity, graph, entity.geometry(graph));
52538             }), 'id');
52539         }
52540
52541
52542         function mouseup() {
52543             select(window)
52544                 .on('mousemove.lasso', null)
52545                 .on('mouseup.lasso', null);
52546
52547             if (!lasso) return;
52548
52549             var ids = lassoed();
52550             lasso.close();
52551
52552             if (ids.length) {
52553                 context.enter(modeSelect(context, ids));
52554             }
52555         }
52556
52557         selection$$1
52558             .on('mousedown.lasso', mousedown);
52559     };
52560
52561
52562     behavior.off = function(selection$$1) {
52563         selection$$1.on('mousedown.lasso', null);
52564     };
52565
52566
52567     return behavior;
52568 }
52569
52570 /* Creates a keybinding behavior for an operation */
52571 function behaviorOperation() {
52572     var which, keybinding;
52573
52574
52575     function drawIcon(selection$$1) {
52576         var button = selection$$1
52577             .append('svg')
52578             .attr('class', 'operation-icon')
52579             .append('g')
52580             .attr('class', 'radial-menu-item radial-menu-item-' + which.id)
52581             .attr('transform', 'translate(10,10)')
52582             .classed('disabled', which.disabled());
52583
52584         button
52585             .append('circle')
52586             .attr('r', 9);
52587
52588         button
52589             .append('use')
52590             .attr('transform', 'translate(-7,-7)')
52591             .attr('width', '14')
52592             .attr('height', '14')
52593             .attr('xlink:href', '#operation-' + which.id);
52594
52595         return selection$$1;
52596     }
52597
52598
52599     var behavior = function () {
52600         if (which && which.available()) {
52601             keybinding = d3keybinding('behavior.key.' + which.id);
52602             keybinding.on(which.keys, function() {
52603                 event.preventDefault();
52604                 var disabled = which.disabled();
52605
52606                 if (disabled) {
52607                     uiFlash(3000)
52608                         .html('')
52609                         .call(drawIcon)
52610                         .append('div')
52611                         .attr('class', 'operation-tip')
52612                         .text(which.tooltip);
52613
52614                 } else {
52615                     uiFlash(1500)
52616                         .html('')
52617                         .call(drawIcon)
52618                         .append('div')
52619                         .attr('class', 'operation-tip')
52620                         .text(which.annotation() || which.title);
52621
52622                     which();
52623                 }
52624             });
52625             select(document).call(keybinding);
52626         }
52627         return behavior;
52628     };
52629
52630
52631     behavior.off = function() {
52632         if (keybinding) {
52633             select(document).call(keybinding.off);
52634         }
52635     };
52636
52637
52638     behavior.which = function (_) {
52639         if (!arguments.length) return which;
52640         which = _;
52641         return behavior;
52642     };
52643
52644
52645     return behavior;
52646 }
52647
52648 function behaviorPaste(context) {
52649     var keybinding = d3keybinding('paste');
52650
52651
52652     function doPaste() {
52653         event.preventDefault();
52654
52655         var baseGraph = context.graph(),
52656             mouse$$1 = context.mouse(),
52657             projection$$1 = context.projection,
52658             viewport = geoExtent$$1(projection$$1.clipExtent()).polygon();
52659
52660         if (!geoPointInPolygon(mouse$$1, viewport)) return;
52661
52662         var extent$$1 = geoExtent$$1(),
52663             oldIDs = context.copyIDs(),
52664             oldGraph = context.copyGraph(),
52665             newIDs = [];
52666
52667         if (!oldIDs.length) return;
52668
52669         var action = actionCopyEntities(oldIDs, oldGraph);
52670         context.perform(action);
52671
52672         var copies = action.copies();
52673         var originals = lodash.invert(lodash.mapValues(copies, 'id'));
52674         for (var id in copies) {
52675             var oldEntity = oldGraph.entity(id),
52676                 newEntity = copies[id];
52677
52678             extent$$1._extend(oldEntity.extent(oldGraph));
52679
52680             // Exclude child nodes from newIDs if their parent way was also copied.
52681             var parents = context.graph().parentWays(newEntity),
52682                 parentCopied = false;
52683             for (var i = 0; i < parents.length; i++) {
52684                 if (originals[parents[i].id]) {
52685                     parentCopied = true;
52686                     break;
52687                 }
52688             }
52689
52690             if (!parentCopied) {
52691                 newIDs.push(newEntity.id);
52692             }
52693         }
52694
52695         // Put pasted objects where mouse pointer is..
52696         var center = projection$$1(extent$$1.center()),
52697             delta = [ mouse$$1[0] - center[0], mouse$$1[1] - center[1] ];
52698
52699         context.perform(actionMove(newIDs, delta, projection$$1));
52700         context.enter(modeMove$$1(context, newIDs, baseGraph));
52701     }
52702
52703
52704     function paste() {
52705         keybinding.on(uiCmd('⌘V'), doPaste);
52706         select(document).call(keybinding);
52707         return paste;
52708     }
52709
52710
52711     paste.off = function() {
52712         select(document).call(keybinding.off);
52713     };
52714
52715
52716     return paste;
52717 }
52718
52719 function behaviorSelect(context) {
52720     var lastMouse = null,
52721         suppressMenu = true,
52722         tolerance = 4,
52723         p1 = null;
52724
52725
52726     function point() {
52727         return mouse(context.container().node());
52728     }
52729
52730
52731     function keydown() {
52732         var e = event;
52733         if (e && e.shiftKey) {
52734             context.surface()
52735                 .classed('behavior-multiselect', true);
52736         }
52737
52738         if (e && e.keyCode === 93) {  // context menu
52739             e.preventDefault();
52740             e.stopPropagation();
52741         }
52742     }
52743
52744
52745     function keyup() {
52746         var e = event;
52747         if (!e || !e.shiftKey) {
52748             context.surface()
52749                 .classed('behavior-multiselect', false);
52750         }
52751
52752
52753         if (e && e.keyCode === 93) {  // context menu
52754             e.preventDefault();
52755             e.stopPropagation();
52756             contextmenu();
52757         }
52758     }
52759
52760
52761     function mousedown() {
52762         if (!p1) p1 = point();
52763         select(window)
52764             .on('mouseup.select', mouseup, true);
52765
52766         var isShowAlways = +context.storage('edit-menu-show-always') === 1;
52767         suppressMenu = !isShowAlways;
52768     }
52769
52770
52771     function mousemove() {
52772         if (event) lastMouse = event;
52773     }
52774
52775
52776     function mouseup() {
52777         click();
52778     }
52779
52780
52781     function contextmenu() {
52782         var e = event;
52783         e.preventDefault();
52784         e.stopPropagation();
52785
52786         if (!+e.clientX && !+e.clientY) {
52787             if (lastMouse) {
52788                 e.sourceEvent = lastMouse;
52789             } else {
52790                 return;
52791             }
52792         }
52793
52794         if (!p1) p1 = point();
52795         suppressMenu = false;
52796         click();
52797     }
52798
52799
52800     function click() {
52801         select(window)
52802             .on('mouseup.select', null, true);
52803
52804         if (!p1) return;
52805         var p2 = point(),
52806             dist = geoEuclideanDistance(p1, p2);
52807
52808         p1 = null;
52809         if (dist > tolerance) {
52810             return;
52811         }
52812
52813         var isMultiselect = event.shiftKey || select('#surface .lasso').node(),
52814             isShowAlways = +context.storage('edit-menu-show-always') === 1,
52815             datum = event.target.__data__ || (lastMouse && lastMouse.target.__data__),
52816             mode = context.mode();
52817
52818
52819         if (datum && datum.type === 'midpoint') {
52820             datum = datum.parents[0];
52821         }
52822
52823         if (!(datum instanceof osmEntity$$1)) {
52824             // clicked nothing..
52825             if (!isMultiselect && mode.id !== 'browse') {
52826                 context.enter(modeBrowse(context));
52827             }
52828
52829         } else {
52830             // clicked an entity..
52831             var selectedIDs = context.selectedIDs();
52832
52833             if (!isMultiselect) {
52834                 if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
52835                     // multiple things already selected, just show the menu...
52836                     mode.suppressMenu(false).reselect();
52837                 } else {
52838                     // select a single thing..
52839                     context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
52840                 }
52841
52842             } else {
52843                 if (selectedIDs.indexOf(datum.id) !== -1) {
52844                     // clicked entity is already in the selectedIDs list..
52845                     if (!suppressMenu && !isShowAlways) {
52846                         // don't deselect clicked entity, just show the menu.
52847                         mode.suppressMenu(false).reselect();
52848                     } else {
52849                         // deselect clicked entity, then reenter select mode or return to browse mode..
52850                         selectedIDs = lodash.without(selectedIDs, datum.id);
52851                         context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
52852                     }
52853                 } else {
52854                     // clicked entity is not in the selected list, add it..
52855                     selectedIDs = selectedIDs.concat([datum.id]);
52856                     context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
52857                 }
52858             }
52859         }
52860
52861         // reset for next time..
52862         suppressMenu = true;
52863     }
52864
52865
52866     var behavior = function(selection$$1) {
52867         lastMouse = null;
52868         suppressMenu = true;
52869         p1 = null;
52870
52871         select(window)
52872             .on('keydown.select', keydown)
52873             .on('keyup.select', keyup)
52874             .on('contextmenu.select-window', function() {
52875                 // Edge and IE really like to show the contextmenu on the
52876                 // menubar when user presses a keyboard menu button
52877                 // even after we've already preventdefaulted the key event.
52878                 var e = event;
52879                 if (+e.clientX === 0 && +e.clientY === 0) {
52880                     event.preventDefault();
52881                     event.stopPropagation();
52882                 }
52883             });
52884
52885         selection$$1
52886             .on('mousedown.select', mousedown)
52887             .on('mousemove.select', mousemove)
52888             .on('contextmenu.select', contextmenu);
52889
52890         if (event && event.shiftKey) {
52891             context.surface()
52892                 .classed('behavior-multiselect', true);
52893         }
52894     };
52895
52896
52897     behavior.off = function(selection$$1) {
52898         select(window)
52899             .on('keydown.select', null)
52900             .on('keyup.select', null)
52901             .on('contextmenu.select-window', null)
52902             .on('mouseup.select', null, true);
52903
52904         selection$$1
52905             .on('mousedown.select', null)
52906             .on('mousemove.select', null)
52907             .on('contextmenu.select', null);
52908
52909         context.surface()
52910             .classed('behavior-multiselect', false);
52911     };
52912
52913
52914     return behavior;
52915 }
52916
52917 function modeAddArea$$1(context) {
52918     var mode = {
52919         id: 'add-area',
52920         button: 'area',
52921         title: t('modes.add_area.title'),
52922         description: t('modes.add_area.description'),
52923         key: '3'
52924     };
52925
52926     var behavior = behaviorAddWay(context)
52927             .tail(t('modes.add_area.tail'))
52928             .on('start', start)
52929             .on('startFromWay', startFromWay)
52930             .on('startFromNode', startFromNode),
52931         defaultTags = { area: 'yes' };
52932
52933
52934     function actionClose(wayId) {
52935         return function (graph) {
52936             return graph.replace(graph.entity(wayId).close());
52937         };
52938     }
52939
52940
52941     function start(loc) {
52942         var startGraph = context.graph(),
52943             node = osmNode({ loc: loc }),
52944             way = osmWay({ tags: defaultTags });
52945
52946         context.perform(
52947             actionAddEntity(node),
52948             actionAddEntity(way),
52949             actionAddVertex(way.id, node.id),
52950             actionClose(way.id)
52951         );
52952
52953         context.enter(modeDrawArea(context, way.id, startGraph));
52954     }
52955
52956
52957     function startFromWay(loc, edge) {
52958         var startGraph = context.graph(),
52959             node = osmNode({ loc: loc }),
52960             way = osmWay({ tags: defaultTags });
52961
52962         context.perform(
52963             actionAddEntity(node),
52964             actionAddEntity(way),
52965             actionAddVertex(way.id, node.id),
52966             actionClose(way.id),
52967             actionAddMidpoint({ loc: loc, edge: edge }, node)
52968         );
52969
52970         context.enter(modeDrawArea(context, way.id, startGraph));
52971     }
52972
52973
52974     function startFromNode(node) {
52975         var startGraph = context.graph(),
52976             way = osmWay({ tags: defaultTags });
52977
52978         context.perform(
52979             actionAddEntity(way),
52980             actionAddVertex(way.id, node.id),
52981             actionClose(way.id)
52982         );
52983
52984         context.enter(modeDrawArea(context, way.id, startGraph));
52985     }
52986
52987
52988     mode.enter = function() {
52989         context.install(behavior);
52990     };
52991
52992
52993     mode.exit = function() {
52994         context.uninstall(behavior);
52995     };
52996
52997
52998     return mode;
52999 }
53000
53001 function modeAddLine$$1(context) {
53002     var mode = {
53003         id: 'add-line',
53004         button: 'line',
53005         title: t('modes.add_line.title'),
53006         description: t('modes.add_line.description'),
53007         key: '2'
53008     };
53009
53010     var behavior = behaviorAddWay(context)
53011         .tail(t('modes.add_line.tail'))
53012         .on('start', start)
53013         .on('startFromWay', startFromWay)
53014         .on('startFromNode', startFromNode);
53015
53016
53017     function start(loc) {
53018         var startGraph = context.graph(),
53019             node = osmNode({ loc: loc }),
53020             way = osmWay();
53021
53022         context.perform(
53023             actionAddEntity(node),
53024             actionAddEntity(way),
53025             actionAddVertex(way.id, node.id)
53026         );
53027
53028         context.enter(modeDrawLine(context, way.id, startGraph));
53029     }
53030
53031
53032     function startFromWay(loc, edge) {
53033         var startGraph = context.graph(),
53034             node = osmNode({ loc: loc }),
53035             way = osmWay();
53036
53037         context.perform(
53038             actionAddEntity(node),
53039             actionAddEntity(way),
53040             actionAddVertex(way.id, node.id),
53041             actionAddMidpoint({ loc: loc, edge: edge }, node)
53042         );
53043
53044         context.enter(modeDrawLine(context, way.id, startGraph));
53045     }
53046
53047
53048     function startFromNode(node) {
53049         var startGraph = context.graph(),
53050             way = osmWay();
53051
53052         context.perform(
53053             actionAddEntity(way),
53054             actionAddVertex(way.id, node.id)
53055         );
53056
53057         context.enter(modeDrawLine(context, way.id, startGraph));
53058     }
53059
53060
53061     mode.enter = function() {
53062         context.install(behavior);
53063     };
53064
53065
53066     mode.exit = function() {
53067         context.uninstall(behavior);
53068     };
53069
53070     return mode;
53071 }
53072
53073 function modeAddPoint$$1(context) {
53074     var mode = {
53075         id: 'add-point',
53076         button: 'point',
53077         title: t('modes.add_point.title'),
53078         description: t('modes.add_point.description'),
53079         key: '1'
53080     };
53081
53082     var behavior = behaviorDraw(context)
53083         .tail(t('modes.add_point.tail'))
53084         .on('click', add)
53085         .on('clickWay', addWay)
53086         .on('clickNode', addNode)
53087         .on('cancel', cancel)
53088         .on('finish', cancel);
53089
53090
53091     function add(loc) {
53092         var node = osmNode({ loc: loc });
53093
53094         context.perform(
53095             actionAddEntity(node),
53096             t('operations.add.annotation.point')
53097         );
53098
53099         context.enter(
53100             modeSelect(context, [node.id]).newFeature(true)
53101         );
53102     }
53103
53104
53105     function addWay(loc) {
53106         add(loc);
53107     }
53108
53109
53110     function addNode(node) {
53111         add(node.loc);
53112     }
53113
53114
53115     function cancel() {
53116         context.enter(modeBrowse(context));
53117     }
53118
53119
53120     mode.enter = function() {
53121         context.install(behavior);
53122     };
53123
53124
53125     mode.exit = function() {
53126         context.uninstall(behavior);
53127     };
53128
53129
53130     return mode;
53131 }
53132
53133 function modeDragNode$$1(context) {
53134     var mode = {
53135         id: 'drag-node',
53136         button: 'browse'
53137     };
53138
53139     var nudgeInterval,
53140         activeIDs,
53141         wasMidpoint,
53142         isCancelled,
53143         lastLoc,
53144         selectedIDs = [],
53145         hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
53146         edit = behaviorEdit(context);
53147
53148
53149     function vecSub(a, b) {
53150         return [a[0] - b[0], a[1] - b[1]];
53151     }
53152
53153     function edge(point, size) {
53154         var pad = [80, 20, 50, 20],   // top, right, bottom, left
53155             x = 0,
53156             y = 0;
53157
53158         if (point[0] > size[0] - pad[1])
53159             x = -10;
53160         if (point[0] < pad[3])
53161             x = 10;
53162         if (point[1] > size[1] - pad[2])
53163             y = -10;
53164         if (point[1] < pad[0])
53165             y = 10;
53166
53167         if (x || y) {
53168             return [x, y];
53169         } else {
53170             return null;
53171         }
53172     }
53173
53174
53175     function startNudge(entity, nudge) {
53176         if (nudgeInterval) window.clearInterval(nudgeInterval);
53177         nudgeInterval = window.setInterval(function() {
53178             context.pan(nudge);
53179             doMove(entity, nudge);
53180         }, 50);
53181     }
53182
53183
53184     function stopNudge() {
53185         if (nudgeInterval) {
53186             window.clearInterval(nudgeInterval);
53187             nudgeInterval = null;
53188         }
53189     }
53190
53191
53192     function moveAnnotation(entity) {
53193         return t('operations.move.annotation.' + entity.geometry(context.graph()));
53194     }
53195
53196
53197     function connectAnnotation(entity) {
53198         return t('operations.connect.annotation.' + entity.geometry(context.graph()));
53199     }
53200
53201
53202     function origin(entity) {
53203         return context.projection(entity.loc);
53204     }
53205
53206
53207     function start(entity) {
53208         wasMidpoint = entity.type === 'midpoint';
53209
53210         isCancelled = event.sourceEvent.shiftKey ||
53211             context.features().hasHiddenConnections(entity, context.graph());
53212
53213         if (isCancelled) {
53214             return behavior.cancel();
53215         }
53216
53217         if (wasMidpoint) {
53218             var midpoint = entity;
53219             entity = osmNode();
53220             context.perform(actionAddMidpoint(midpoint, entity));
53221
53222             var vertex = context.surface().selectAll('.' + entity.id);
53223             behavior.target(vertex.node(), entity);
53224
53225         } else {
53226             context.perform(actionNoop());
53227         }
53228
53229         // activeIDs generate no pointer events.  This prevents the node or vertex
53230         // being dragged from trying to connect to itself or its parent element.
53231         activeIDs = lodash.map(context.graph().parentWays(entity), 'id');
53232         activeIDs.push(entity.id);
53233         setActiveElements();
53234
53235         context.enter(mode);
53236     }
53237
53238
53239     function datum() {
53240         var event$$1 = event && event.sourceEvent;
53241         if (!event$$1 || event$$1.altKey) {
53242             return {};
53243         } else {
53244             return event$$1.target.__data__ || {};
53245         }
53246     }
53247
53248
53249     function doMove(entity, nudge) {
53250         nudge = nudge || [0, 0];
53251
53252         var currPoint = (event && event.point) || context.projection(lastLoc),
53253             currMouse = vecSub(currPoint, nudge),
53254             loc = context.projection.invert(currMouse),
53255             d = datum();
53256
53257         if (!nudgeInterval) {
53258             if (d.type === 'node' && d.id !== entity.id) {
53259                 loc = d.loc;
53260             } else if (d.type === 'way' && !select(event.sourceEvent.target).classed('fill')) {
53261                 loc = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
53262             }
53263         }
53264
53265         context.replace(
53266             actionMoveNode(entity.id, loc),
53267             moveAnnotation(entity)
53268         );
53269
53270         lastLoc = loc;
53271     }
53272
53273
53274     function move(entity) {
53275         if (isCancelled) return;
53276         event.sourceEvent.stopPropagation();
53277         lastLoc = context.projection.invert(event.point);
53278
53279         doMove(entity);
53280         var nudge = edge(event.point, context.map().dimensions());
53281         if (nudge) {
53282             startNudge(entity, nudge);
53283         } else {
53284             stopNudge();
53285         }
53286     }
53287
53288
53289     function end(entity) {
53290         if (isCancelled) return;
53291
53292         var d = datum();
53293
53294         if (d.type === 'way') {
53295             var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
53296             context.replace(
53297                 actionAddMidpoint({ loc: choice.loc, edge: [d.nodes[choice.index - 1], d.nodes[choice.index]] }, entity),
53298                 connectAnnotation(d)
53299             );
53300
53301         } else if (d.type === 'node' && d.id !== entity.id) {
53302             context.replace(
53303                 actionConnect([d.id, entity.id]),
53304                 connectAnnotation(d)
53305             );
53306
53307         } else if (wasMidpoint) {
53308             context.replace(
53309                 actionNoop(),
53310                 t('operations.add.annotation.vertex')
53311             );
53312
53313         } else {
53314             context.replace(
53315                 actionNoop(),
53316                 moveAnnotation(entity)
53317             );
53318         }
53319
53320         var reselection = selectedIDs.filter(function(id) {
53321             return context.graph().hasEntity(id);
53322         });
53323
53324         if (reselection.length) {
53325             context.enter(modeSelect(context, reselection));
53326         } else {
53327             context.enter(modeBrowse(context));
53328         }
53329     }
53330
53331
53332     function cancel() {
53333         behavior.cancel();
53334         context.enter(modeBrowse(context));
53335     }
53336
53337
53338     function setActiveElements() {
53339         context.surface().selectAll(utilEntitySelector(activeIDs))
53340             .classed('active', true);
53341     }
53342
53343
53344     var behavior = behaviorDrag()
53345         .selector('g.node, g.point, g.midpoint')
53346         .surface(select('#map').node())
53347         .origin(origin)
53348         .on('start', start)
53349         .on('move', move)
53350         .on('end', end);
53351
53352
53353     mode.enter = function() {
53354         context.install(hover);
53355         context.install(edit);
53356
53357         context.history()
53358             .on('undone.drag-node', cancel);
53359
53360         context.map()
53361             .on('drawn.drag-node', setActiveElements);
53362
53363         setActiveElements();
53364     };
53365
53366
53367     mode.exit = function() {
53368         context.ui().sidebar.hover.cancel();
53369         context.uninstall(hover);
53370         context.uninstall(edit);
53371
53372         context.history()
53373             .on('undone.drag-node', null);
53374
53375         context.map()
53376             .on('drawn.drag-node', null);
53377
53378         context.surface()
53379             .selectAll('.active')
53380             .classed('active', false);
53381
53382         stopNudge();
53383     };
53384
53385
53386     mode.selectedIDs = function(_) {
53387         if (!arguments.length) return selectedIDs;
53388         selectedIDs = _;
53389         return mode;
53390     };
53391
53392
53393     mode.behavior = behavior;
53394
53395
53396     return mode;
53397 }
53398
53399 function modeBrowse(context) {
53400     var mode = {
53401         button: 'browse',
53402         id: 'browse',
53403         title: t('modes.browse.title'),
53404         description: t('modes.browse.description')
53405     }, sidebar;
53406
53407     var behaviors = [
53408         behaviorPaste(context),
53409         behaviorHover(context).on('hover', context.ui().sidebar.hover),
53410         behaviorSelect(context),
53411         behaviorLasso(context),
53412         modeDragNode$$1(context).behavior
53413     ];
53414
53415
53416     mode.enter = function() {
53417         behaviors.forEach(function(behavior) {
53418             context.install(behavior);
53419         });
53420
53421         // Get focus on the body.
53422         if (document.activeElement && document.activeElement.blur) {
53423             document.activeElement.blur();
53424         }
53425
53426         if (sidebar) {
53427             context.ui().sidebar.show(sidebar);
53428         } else {
53429             context.ui().sidebar.select(null);
53430         }
53431     };
53432
53433
53434     mode.exit = function() {
53435         context.ui().sidebar.hover.cancel();
53436         behaviors.forEach(function(behavior) {
53437             context.uninstall(behavior);
53438         });
53439
53440         if (sidebar) {
53441             context.ui().sidebar.hide();
53442         }
53443     };
53444
53445
53446     mode.sidebar = function(_) {
53447         if (!arguments.length) return sidebar;
53448         sidebar = _;
53449         return mode;
53450     };
53451
53452
53453     return mode;
53454 }
53455
53456 function modeDrawArea(context, wayId, startGraph) {
53457     var mode = {
53458         button: 'area',
53459         id: 'draw-area'
53460     };
53461
53462     var behavior;
53463
53464
53465     mode.enter = function() {
53466         var way = context.entity(wayId);
53467
53468         behavior = behaviorDrawWay(context, wayId, undefined, mode, startGraph)
53469             .tail(t('modes.draw_area.tail'));
53470
53471         var addNode = behavior.addNode;
53472
53473         behavior.addNode = function(node) {
53474             var length = way.nodes.length,
53475                 penultimate = length > 2 ? way.nodes[length - 2] : null;
53476
53477             if (node.id === way.first() || node.id === penultimate) {
53478                 behavior.finish();
53479             } else {
53480                 addNode(node);
53481             }
53482         };
53483
53484         context.install(behavior);
53485     };
53486
53487
53488     mode.exit = function() {
53489         context.uninstall(behavior);
53490     };
53491
53492
53493     mode.selectedIDs = function() {
53494         return [wayId];
53495     };
53496
53497
53498     return mode;
53499 }
53500
53501 function modeDrawLine(context, wayId, startGraph, affix) {
53502     var mode = {
53503         button: 'line',
53504         id: 'draw-line'
53505     };
53506
53507     var behavior;
53508
53509
53510     mode.enter = function() {
53511         var way = context.entity(wayId),
53512             index = (affix === 'prefix') ? 0 : undefined,
53513             headId = (affix === 'prefix') ? way.first() : way.last();
53514
53515         behavior = behaviorDrawWay(context, wayId, index, mode, startGraph)
53516             .tail(t('modes.draw_line.tail'));
53517
53518         var addNode = behavior.addNode;
53519
53520         behavior.addNode = function(node) {
53521             if (node.id === headId) {
53522                 behavior.finish();
53523             } else {
53524                 addNode(node);
53525             }
53526         };
53527
53528         context.install(behavior);
53529     };
53530
53531
53532     mode.exit = function() {
53533         context.uninstall(behavior);
53534     };
53535
53536
53537     mode.selectedIDs = function() {
53538         return [wayId];
53539     };
53540
53541
53542     return mode;
53543 }
53544
53545 function operationCircularize(selectedIDs, context) {
53546     var entityId = selectedIDs[0],
53547         entity = context.entity(entityId),
53548         extent = entity.extent(context.graph()),
53549         geometry = context.geometry(entityId),
53550         action = actionCircularize(entityId, context.projection);
53551
53552
53553     var operation = function() {
53554         context.perform(action, operation.annotation());
53555     };
53556
53557
53558     operation.available = function() {
53559         return selectedIDs.length === 1 &&
53560             entity.type === 'way' &&
53561             lodash.uniq(entity.nodes).length > 1;
53562     };
53563
53564
53565     operation.disabled = function() {
53566         var reason;
53567         if (extent.percentContainedIn(context.extent()) < 0.8) {
53568             reason = 'too_large';
53569         } else if (context.hasHiddenConnections(entityId)) {
53570             reason = 'connected_to_hidden';
53571         }
53572         return action.disabled(context.graph()) || reason;
53573     };
53574
53575
53576     operation.tooltip = function() {
53577         var disable = operation.disabled();
53578         return disable ?
53579             t('operations.circularize.' + disable) :
53580             t('operations.circularize.description.' + geometry);
53581     };
53582
53583
53584     operation.annotation = function() {
53585         return t('operations.circularize.annotation.' + geometry);
53586     };
53587
53588
53589     operation.id = 'circularize';
53590     operation.keys = [t('operations.circularize.key')];
53591     operation.title = t('operations.circularize.title');
53592     operation.behavior = behaviorOperation(context).which(operation);
53593
53594     return operation;
53595 }
53596
53597 function operationContinue(selectedIDs, context) {
53598     var graph = context.graph(),
53599         entities = selectedIDs.map(function(id) { return graph.entity(id); }),
53600         geometries = lodash.extend({ line: [], vertex: [] },
53601             lodash.groupBy(entities, function(entity) { return entity.geometry(graph); })),
53602         vertex = geometries.vertex[0];
53603
53604
53605     function candidateWays() {
53606         return graph.parentWays(vertex).filter(function(parent) {
53607             return parent.geometry(graph) === 'line' &&
53608                 !parent.isClosed() &&
53609                 parent.affix(vertex.id) &&
53610                 (geometries.line.length === 0 || geometries.line[0] === parent);
53611         });
53612     }
53613
53614
53615     var operation = function() {
53616         var candidate = candidateWays()[0];
53617         context.enter(
53618             modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
53619         );
53620     };
53621
53622
53623     operation.available = function() {
53624         return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
53625             !context.features().hasHiddenConnections(vertex, context.graph());
53626     };
53627
53628
53629     operation.disabled = function() {
53630         var candidates = candidateWays();
53631         if (candidates.length === 0)
53632             return 'not_eligible';
53633         if (candidates.length > 1)
53634             return 'multiple';
53635     };
53636
53637
53638     operation.tooltip = function() {
53639         var disable = operation.disabled();
53640         return disable ?
53641             t('operations.continue.' + disable) :
53642             t('operations.continue.description');
53643     };
53644
53645
53646     operation.annotation = function() {
53647         return t('operations.continue.annotation.line');
53648     };
53649
53650
53651     operation.id = 'continue';
53652     operation.keys = [t('operations.continue.key')];
53653     operation.title = t('operations.continue.title');
53654     operation.behavior = behaviorOperation(context).which(operation);
53655
53656     return operation;
53657 }
53658
53659 function operationDelete(selectedIDs, context) {
53660     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
53661         action = actionDeleteMultiple(selectedIDs),
53662         extent = selectedIDs.reduce(function(extent, id) {
53663                 return extent.extend(context.entity(id).extent(context.graph()));
53664             }, geoExtent$$1());
53665
53666
53667     var operation = function() {
53668         var nextSelectedID;
53669
53670         if (selectedIDs.length === 1) {
53671             var id = selectedIDs[0],
53672                 entity = context.entity(id),
53673                 geometry = context.geometry(id),
53674                 parents = context.graph().parentWays(entity),
53675                 parent = parents[0];
53676
53677             // Select the next closest node in the way.
53678             if (geometry === 'vertex' && parent.nodes.length > 2) {
53679                 var nodes = parent.nodes,
53680                     i = nodes.indexOf(id);
53681
53682                 if (i === 0) {
53683                     i++;
53684                 } else if (i === nodes.length - 1) {
53685                     i--;
53686                 } else {
53687                     var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
53688                         b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
53689                     i = a < b ? i - 1 : i + 1;
53690                 }
53691
53692                 nextSelectedID = nodes[i];
53693             }
53694         }
53695
53696         context.perform(action, operation.annotation());
53697
53698         if (nextSelectedID && context.hasEntity(nextSelectedID)) {
53699             context.enter(modeSelect(context, [nextSelectedID]).follow(true));
53700         } else {
53701             context.enter(modeBrowse(context));
53702         }
53703
53704     };
53705
53706
53707     operation.available = function() {
53708         return true;
53709     };
53710
53711
53712     operation.disabled = function() {
53713         var reason;
53714         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
53715             reason = 'too_large';
53716         } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
53717             reason = 'connected_to_hidden';
53718         } else if (lodash.some(selectedIDs, protectedMember)) {
53719             reason = 'part_of_relation';
53720         } else if (lodash.some(selectedIDs, incompleteRelation)) {
53721             reason = 'incomplete_relation';
53722         }
53723         return reason;
53724
53725         function incompleteRelation(id) {
53726             var entity = context.entity(id);
53727             return entity.type === 'relation' && !entity.isComplete(context.graph());
53728         }
53729
53730         function protectedMember(id) {
53731             var entity = context.entity(id);
53732             if (entity.type !== 'way') return false;
53733
53734             var parents = context.graph().parentRelations(entity);
53735             for (var i = 0; i < parents.length; i++) {
53736                 var parent = parents[i],
53737                     type = parent.tags.type,
53738                     role = parent.memberById(id).role || 'outer';
53739                 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
53740                     return true;
53741                 }
53742             }
53743             return false;
53744         }
53745
53746     };
53747
53748
53749     operation.tooltip = function() {
53750         var disable = operation.disabled();
53751         return disable ?
53752             t('operations.delete.' + disable + '.' + multi) :
53753             t('operations.delete.description' + '.' + multi);
53754     };
53755
53756
53757     operation.annotation = function() {
53758         return selectedIDs.length === 1 ?
53759             t('operations.delete.annotation.' + context.geometry(selectedIDs[0])) :
53760             t('operations.delete.annotation.multiple', { n: selectedIDs.length });
53761     };
53762
53763
53764     operation.id = 'delete';
53765     operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
53766     operation.title = t('operations.delete.title');
53767     operation.behavior = behaviorOperation(context).which(operation);
53768
53769     return operation;
53770 }
53771
53772 function operationDisconnect(selectedIDs, context) {
53773     var vertices = lodash.filter(selectedIDs, function(entityId) {
53774         return context.geometry(entityId) === 'vertex';
53775     });
53776
53777     var entityId = vertices[0],
53778         action = actionDisconnect(entityId);
53779
53780     if (selectedIDs.length > 1) {
53781         action.limitWays(lodash.without(selectedIDs, entityId));
53782     }
53783
53784
53785     var operation = function() {
53786         context.perform(action, operation.annotation());
53787     };
53788
53789
53790     operation.available = function() {
53791         return vertices.length === 1;
53792     };
53793
53794
53795     operation.disabled = function() {
53796         var reason;
53797         if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
53798             reason = 'connected_to_hidden';
53799         }
53800         return action.disabled(context.graph()) || reason;
53801     };
53802
53803
53804     operation.tooltip = function() {
53805         var disable = operation.disabled();
53806         return disable ?
53807             t('operations.disconnect.' + disable) :
53808             t('operations.disconnect.description');
53809     };
53810
53811
53812     operation.annotation = function() {
53813         return t('operations.disconnect.annotation');
53814     };
53815
53816
53817     operation.id = 'disconnect';
53818     operation.keys = [t('operations.disconnect.key')];
53819     operation.title = t('operations.disconnect.title');
53820     operation.behavior = behaviorOperation(context).which(operation);
53821
53822     return operation;
53823 }
53824
53825 function operationMerge(selectedIDs, context) {
53826
53827     function updatePresetTags(newGraph, ids) {
53828         var id = ids[0],
53829             newEntity = newGraph.hasEntity(id);
53830
53831         if (!newEntity) return;
53832
53833         var newPreset = context.presets().match(newEntity, newGraph);
53834
53835         context.replace(actionChangePreset(id, null, newPreset), operation.annotation());
53836     }
53837
53838
53839     var join = actionJoin(selectedIDs),
53840         merge = actionMerge(selectedIDs),
53841         mergePolygon = actionMergePolygon(selectedIDs);
53842
53843
53844     var operation = function() {
53845         var origGraph = context.graph(),
53846             action;
53847
53848         if (!join.disabled(origGraph)) {
53849             action = join;
53850         } else if (!merge.disabled(origGraph)) {
53851             action = merge;
53852         } else {
53853             action = mergePolygon;
53854         }
53855
53856         context.perform(action, operation.annotation());
53857
53858         var ids = selectedIDs.filter(function(id) {
53859             var entity = context.hasEntity(id);
53860             return entity && entity.type !== 'node';
53861         });
53862
53863         // if we merged tags, rematch preset to update tags if necessary (#3851)
53864         if (action === merge) {
53865             updatePresetTags(context.graph(), ids);
53866         }
53867
53868         context.enter(modeSelect(context, ids));
53869     };
53870
53871
53872     operation.available = function() {
53873         return selectedIDs.length >= 2;
53874     };
53875
53876
53877     operation.disabled = function() {
53878         return join.disabled(context.graph()) &&
53879             merge.disabled(context.graph()) &&
53880             mergePolygon.disabled(context.graph());
53881     };
53882
53883
53884     operation.tooltip = function() {
53885         var j = join.disabled(context.graph()),
53886             m = merge.disabled(context.graph()),
53887             p = mergePolygon.disabled(context.graph());
53888
53889         if (j === 'restriction' && m && p) {
53890             return t('operations.merge.restriction',
53891                 { relation: context.presets().item('type/restriction').name() });
53892         }
53893
53894         if (p === 'incomplete_relation' && j && m) {
53895             return t('operations.merge.incomplete_relation');
53896         }
53897
53898         if (j && m && p) {
53899             return t('operations.merge.' + j);
53900         }
53901
53902         return t('operations.merge.description');
53903     };
53904
53905
53906     operation.annotation = function() {
53907         return t('operations.merge.annotation', { n: selectedIDs.length });
53908     };
53909
53910
53911     operation.id = 'merge';
53912     operation.keys = [t('operations.merge.key')];
53913     operation.title = t('operations.merge.title');
53914     operation.behavior = behaviorOperation(context).which(operation);
53915
53916     return operation;
53917 }
53918
53919 function operationMove(selectedIDs, context) {
53920     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
53921         extent = selectedIDs.reduce(function(extent, id) {
53922             return extent.extend(context.entity(id).extent(context.graph()));
53923         }, geoExtent$$1());
53924
53925
53926     var operation = function() {
53927         context.enter(modeMove$$1(context, selectedIDs));
53928     };
53929
53930
53931     operation.available = function() {
53932         return selectedIDs.length > 1 ||
53933             context.entity(selectedIDs[0]).type !== 'node';
53934     };
53935
53936
53937     operation.disabled = function() {
53938         var reason;
53939         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
53940             reason = 'too_large';
53941         } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
53942             reason = 'connected_to_hidden';
53943         } else if (lodash.some(selectedIDs, incompleteRelation)) {
53944             reason = 'incomplete_relation';
53945         }
53946         return reason;
53947
53948         function incompleteRelation(id) {
53949             var entity = context.entity(id);
53950             return entity.type === 'relation' && !entity.isComplete(context.graph());
53951         }
53952     };
53953
53954
53955     operation.tooltip = function() {
53956         var disable = operation.disabled();
53957         return disable ?
53958             t('operations.move.' + disable + '.' + multi) :
53959             t('operations.move.description.' + multi);
53960     };
53961
53962
53963     operation.annotation = function() {
53964         return selectedIDs.length === 1 ?
53965             t('operations.move.annotation.' + context.geometry(selectedIDs[0])) :
53966             t('operations.move.annotation.multiple');
53967     };
53968
53969
53970     operation.id = 'move';
53971     operation.keys = [t('operations.move.key')];
53972     operation.title = t('operations.move.title');
53973     operation.behavior = behaviorOperation(context).which(operation);
53974
53975     return operation;
53976 }
53977
53978 function operationOrthogonalize(selectedIDs, context) {
53979     var entityId = selectedIDs[0],
53980         entity = context.entity(entityId),
53981         extent = entity.extent(context.graph()),
53982         geometry = context.geometry(entityId),
53983         action = actionOrthogonalize(entityId, context.projection);
53984
53985
53986     var operation = function() {
53987         context.perform(action, operation.annotation());
53988     };
53989
53990
53991     operation.available = function() {
53992         return selectedIDs.length === 1 &&
53993             entity.type === 'way' &&
53994             entity.isClosed() &&
53995             lodash.uniq(entity.nodes).length > 2;
53996     };
53997
53998
53999     operation.disabled = function() {
54000         var reason;
54001         if (extent.percentContainedIn(context.extent()) < 0.8) {
54002             reason = 'too_large';
54003         } else if (context.hasHiddenConnections(entityId)) {
54004             reason = 'connected_to_hidden';
54005         }
54006         return action.disabled(context.graph()) || reason;
54007     };
54008
54009
54010     operation.tooltip = function() {
54011         var disable = operation.disabled();
54012         return disable ?
54013             t('operations.orthogonalize.' + disable) :
54014             t('operations.orthogonalize.description.' + geometry);
54015     };
54016
54017
54018     operation.annotation = function() {
54019         return t('operations.orthogonalize.annotation.' + geometry);
54020     };
54021
54022
54023     operation.id = 'orthogonalize';
54024     operation.keys = [t('operations.orthogonalize.key')];
54025     operation.title = t('operations.orthogonalize.title');
54026     operation.behavior = behaviorOperation(context).which(operation);
54027
54028     return operation;
54029 }
54030
54031 function operationReflectShort(selectedIDs, context) {
54032     return operationReflect(selectedIDs, context, 'short');
54033 }
54034
54035
54036 function operationReflectLong(selectedIDs, context) {
54037     return operationReflect(selectedIDs, context, 'long');
54038 }
54039
54040
54041 function operationReflect(selectedIDs, context, axis) {
54042     axis = axis || 'long';
54043     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
54044         extent = selectedIDs.reduce(function(extent, id) {
54045             return extent.extend(context.entity(id).extent(context.graph()));
54046         }, geoExtent$$1());
54047
54048
54049     var operation = function() {
54050         var action = actionReflect(selectedIDs, context.projection)
54051             .useLongAxis(Boolean(axis === 'long'));
54052         context.perform(action, operation.annotation());
54053     };
54054
54055
54056     operation.available = function() {
54057         var nodes = utilGetAllNodes(selectedIDs, context.graph());
54058         return lodash.uniqBy(nodes, function(n) { return n.loc; }).length >= 3;
54059     };
54060
54061
54062     operation.disabled = function() {
54063         var reason;
54064         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
54065             reason = 'too_large';
54066         } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
54067             reason = 'connected_to_hidden';
54068         } else if (lodash.some(selectedIDs, incompleteRelation)) {
54069             reason = 'incomplete_relation';
54070         }
54071         return reason;
54072
54073         function incompleteRelation(id) {
54074             var entity = context.entity(id);
54075             return entity.type === 'relation' && !entity.isComplete(context.graph());
54076         }
54077     };
54078
54079
54080     operation.tooltip = function() {
54081         var disable = operation.disabled();
54082         return disable ?
54083             t('operations.reflect.' + disable + '.' + multi) :
54084             t('operations.reflect.description.' + axis + '.' + multi);
54085     };
54086
54087
54088     operation.annotation = function() {
54089         return t('operations.reflect.annotation.' + axis + '.' + multi);
54090     };
54091
54092
54093     operation.id = 'reflect-' + axis;
54094     operation.keys = [t('operations.reflect.key.' + axis)];
54095     operation.title = t('operations.reflect.title.' + axis);
54096     operation.behavior = behaviorOperation(context).which(operation);
54097
54098     return operation;
54099 }
54100
54101 function operationReverse(selectedIDs, context) {
54102     var entityId = selectedIDs[0];
54103
54104     var operation = function() {
54105         context.perform(actionReverse(entityId), operation.annotation());
54106     };
54107
54108
54109     operation.available = function() {
54110         return selectedIDs.length === 1 && context.geometry(entityId) === 'line';
54111     };
54112
54113
54114     operation.disabled = function() {
54115         return false;
54116     };
54117
54118
54119     operation.tooltip = function() {
54120         return t('operations.reverse.description');
54121     };
54122
54123
54124     operation.annotation = function() {
54125         return t('operations.reverse.annotation');
54126     };
54127
54128
54129     operation.id = 'reverse';
54130     operation.keys = [t('operations.reverse.key')];
54131     operation.title = t('operations.reverse.title');
54132     operation.behavior = behaviorOperation(context).which(operation);
54133
54134     return operation;
54135 }
54136
54137 function operationRotate(selectedIDs, context) {
54138     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
54139         extent = selectedIDs.reduce(function(extent, id) {
54140             return extent.extend(context.entity(id).extent(context.graph()));
54141         }, geoExtent$$1());
54142
54143
54144     var operation = function() {
54145         context.enter(modeRotate$$1(context, selectedIDs));
54146     };
54147
54148
54149     operation.available = function() {
54150         var nodes = utilGetAllNodes(selectedIDs, context.graph());
54151         return lodash.uniqBy(nodes, function(n) { return n.loc; }).length >= 2;
54152     };
54153
54154
54155     operation.disabled = function() {
54156         var reason;
54157         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
54158             reason = 'too_large';
54159         } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
54160             reason = 'connected_to_hidden';
54161         } else if (lodash.some(selectedIDs, incompleteRelation)) {
54162             reason = 'incomplete_relation';
54163         }
54164         return reason;
54165
54166         function incompleteRelation(id) {
54167             var entity = context.entity(id);
54168             return entity.type === 'relation' && !entity.isComplete(context.graph());
54169         }
54170     };
54171
54172
54173     operation.tooltip = function() {
54174         var disable = operation.disabled();
54175         return disable ?
54176             t('operations.rotate.' + disable + '.' + multi) :
54177             t('operations.rotate.description.' + multi);
54178     };
54179
54180
54181     operation.annotation = function() {
54182         return selectedIDs.length === 1 ?
54183             t('operations.rotate.annotation.' + context.geometry(selectedIDs[0])) :
54184             t('operations.rotate.annotation.multiple');
54185     };
54186
54187
54188     operation.id = 'rotate';
54189     operation.keys = [t('operations.rotate.key')];
54190     operation.title = t('operations.rotate.title');
54191     operation.behavior = behaviorOperation(context).which(operation);
54192
54193     return operation;
54194 }
54195
54196 function operationSplit(selectedIDs, context) {
54197     var vertices = lodash.filter(selectedIDs, function(entityId) {
54198         return context.geometry(entityId) === 'vertex';
54199     });
54200
54201     var entityId = vertices[0],
54202         action = actionSplit(entityId),
54203         ways = [];
54204
54205     if (vertices.length === 1) {
54206         if (selectedIDs.length > 1) {
54207             action.limitWays(lodash.without(selectedIDs, entityId));
54208         }
54209         ways = action.ways(context.graph());
54210     }
54211
54212
54213     var operation = function() {
54214         var difference = context.perform(action, operation.annotation());
54215         context.enter(modeSelect(context, difference.extantIDs()));
54216     };
54217
54218
54219     operation.available = function() {
54220         return vertices.length === 1;
54221     };
54222
54223
54224     operation.disabled = function() {
54225         var reason;
54226         if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
54227             reason = 'connected_to_hidden';
54228         }
54229         return action.disabled(context.graph()) || reason;
54230     };
54231
54232
54233     operation.tooltip = function() {
54234         var disable = operation.disabled();
54235         if (disable) {
54236             return t('operations.split.' + disable);
54237         }
54238         if (ways.length === 1) {
54239             return t('operations.split.description.' + context.geometry(ways[0].id));
54240         } else {
54241             return t('operations.split.description.multiple');
54242         }
54243     };
54244
54245
54246     operation.annotation = function() {
54247         return ways.length === 1 ?
54248             t('operations.split.annotation.' + context.geometry(ways[0].id)) :
54249             t('operations.split.annotation.multiple', { n: ways.length });
54250     };
54251
54252
54253     operation.id = 'split';
54254     operation.keys = [t('operations.split.key')];
54255     operation.title = t('operations.split.title');
54256     operation.behavior = behaviorOperation(context).which(operation);
54257
54258     return operation;
54259 }
54260
54261 function operationStraighten(selectedIDs, context) {
54262     var entityId = selectedIDs[0],
54263         action = actionStraighten(entityId, context.projection);
54264
54265
54266     function operation() {
54267         context.perform(action, operation.annotation());
54268     }
54269
54270
54271     operation.available = function() {
54272         var entity = context.entity(entityId);
54273         return selectedIDs.length === 1 &&
54274             entity.type === 'way' &&
54275             !entity.isClosed() &&
54276             lodash.uniq(entity.nodes).length > 2;
54277     };
54278
54279
54280     operation.disabled = function() {
54281         var reason;
54282         if (context.hasHiddenConnections(entityId)) {
54283             reason = 'connected_to_hidden';
54284         }
54285         return action.disabled(context.graph()) || reason;
54286     };
54287
54288
54289     operation.tooltip = function() {
54290         var disable = operation.disabled();
54291         return disable ?
54292             t('operations.straighten.' + disable) :
54293             t('operations.straighten.description');
54294     };
54295
54296
54297     operation.annotation = function() {
54298         return t('operations.straighten.annotation');
54299     };
54300
54301
54302     operation.id = 'straighten';
54303     operation.keys = [t('operations.straighten.key')];
54304     operation.title = t('operations.straighten.title');
54305     operation.behavior = behaviorOperation(context).which(operation);
54306
54307     return operation;
54308 }
54309
54310
54311
54312 var Operations = Object.freeze({
54313         operationCircularize: operationCircularize,
54314         operationContinue: operationContinue,
54315         operationDelete: operationDelete,
54316         operationDisconnect: operationDisconnect,
54317         operationMerge: operationMerge,
54318         operationMove: operationMove,
54319         operationOrthogonalize: operationOrthogonalize,
54320         operationReflectShort: operationReflectShort,
54321         operationReflectLong: operationReflectLong,
54322         operationReverse: operationReverse,
54323         operationRotate: operationRotate,
54324         operationSplit: operationSplit,
54325         operationStraighten: operationStraighten
54326 });
54327
54328 function modeMove$$1(context, entityIDs, baseGraph) {
54329     var mode = {
54330         id: 'move',
54331         button: 'browse'
54332     };
54333
54334     var keybinding = d3keybinding('move'),
54335         behaviors = [
54336             behaviorEdit(context),
54337             operationCircularize(entityIDs, context).behavior,
54338             operationDelete(entityIDs, context).behavior,
54339             operationOrthogonalize(entityIDs, context).behavior,
54340             operationReflectLong(entityIDs, context).behavior,
54341             operationReflectShort(entityIDs, context).behavior,
54342             operationRotate(entityIDs, context).behavior
54343         ],
54344         annotation = entityIDs.length === 1 ?
54345             t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
54346             t('operations.move.annotation.multiple'),
54347         prevGraph,
54348         cache,
54349         origin,
54350         nudgeInterval;
54351
54352
54353     function vecSub(a, b) {
54354         return [a[0] - b[0], a[1] - b[1]];
54355     }
54356
54357
54358     function edge(point, size) {
54359         var pad = [80, 20, 50, 20],   // top, right, bottom, left
54360             x = 0,
54361             y = 0;
54362
54363         if (point[0] > size[0] - pad[1])
54364             x = -10;
54365         if (point[0] < pad[3])
54366             x = 10;
54367         if (point[1] > size[1] - pad[2])
54368             y = -10;
54369         if (point[1] < pad[0])
54370             y = 10;
54371
54372         if (x || y) {
54373             return [x, y];
54374         } else {
54375             return null;
54376         }
54377     }
54378
54379
54380     function doMove(nudge) {
54381         nudge = nudge || [0, 0];
54382
54383         var fn;
54384         if (prevGraph !== context.graph()) {
54385             cache = {};
54386             origin = context.map().mouseCoordinates();
54387             fn = context.perform;
54388         } else {
54389             fn = context.overwrite;
54390         }
54391
54392         var currMouse = context.mouse(),
54393             origMouse = context.projection(origin),
54394             delta = vecSub(vecSub(currMouse, origMouse), nudge);
54395
54396         fn(actionMove(entityIDs, delta, context.projection, cache), annotation);
54397         prevGraph = context.graph();
54398     }
54399
54400
54401     function startNudge(nudge) {
54402         if (nudgeInterval) window.clearInterval(nudgeInterval);
54403         nudgeInterval = window.setInterval(function() {
54404             context.pan(nudge);
54405             doMove(nudge);
54406         }, 50);
54407     }
54408
54409
54410     function stopNudge() {
54411         if (nudgeInterval) {
54412             window.clearInterval(nudgeInterval);
54413             nudgeInterval = null;
54414         }
54415     }
54416
54417
54418     function move() {
54419         doMove();
54420         var nudge = edge(context.mouse(), context.map().dimensions());
54421         if (nudge) {
54422             startNudge(nudge);
54423         } else {
54424             stopNudge();
54425         }
54426     }
54427
54428
54429     function finish() {
54430         event.stopPropagation();
54431         context.enter(modeSelect(context, entityIDs));
54432         stopNudge();
54433     }
54434
54435
54436     function cancel() {
54437         if (baseGraph) {
54438             while (context.graph() !== baseGraph) context.pop();
54439             context.enter(modeBrowse(context));
54440         } else {
54441             context.pop();
54442             context.enter(modeSelect(context, entityIDs));
54443         }
54444         stopNudge();
54445     }
54446
54447
54448     function undone() {
54449         context.enter(modeBrowse(context));
54450     }
54451
54452
54453     mode.enter = function() {
54454         origin = context.map().mouseCoordinates();
54455         prevGraph = null;
54456         cache = {};
54457
54458         behaviors.forEach(function(behavior) {
54459             context.install(behavior);
54460         });
54461
54462         context.surface()
54463             .on('mousemove.move', move)
54464             .on('click.move', finish);
54465
54466         context.history()
54467             .on('undone.move', undone);
54468
54469         keybinding
54470             .on('⎋', cancel)
54471             .on('↩', finish);
54472
54473         select(document)
54474             .call(keybinding);
54475     };
54476
54477
54478     mode.exit = function() {
54479         stopNudge();
54480
54481         behaviors.forEach(function(behavior) {
54482             context.uninstall(behavior);
54483         });
54484
54485         context.surface()
54486             .on('mousemove.move', null)
54487             .on('click.move', null);
54488
54489         context.history()
54490             .on('undone.move', null);
54491
54492         keybinding.off();
54493     };
54494
54495
54496     return mode;
54497 }
54498
54499 function modeRotate$$1(context, entityIDs) {
54500     var mode = {
54501         id: 'rotate',
54502         button: 'browse'
54503     };
54504
54505     var keybinding = d3keybinding('rotate'),
54506         behaviors = [
54507             behaviorEdit(context),
54508             operationCircularize(entityIDs, context).behavior,
54509             operationDelete(entityIDs, context).behavior,
54510             operationMove(entityIDs, context).behavior,
54511             operationOrthogonalize(entityIDs, context).behavior,
54512             operationReflectLong(entityIDs, context).behavior,
54513             operationReflectShort(entityIDs, context).behavior
54514         ],
54515         annotation = entityIDs.length === 1 ?
54516             t('operations.rotate.annotation.' + context.geometry(entityIDs[0])) :
54517             t('operations.rotate.annotation.multiple'),
54518         prevGraph,
54519         prevAngle,
54520         prevTransform,
54521         pivot;
54522
54523
54524     function doRotate() {
54525         var fn;
54526         if (context.graph() !== prevGraph) {
54527             fn = context.perform;
54528         } else {
54529             fn = context.replace;
54530         }
54531
54532         // projection changed, recalculate pivot
54533         var projection$$1 = context.projection;
54534         var currTransform = projection$$1.transform();
54535         if (!prevTransform ||
54536             currTransform.k !== prevTransform.k ||
54537             currTransform.x !== prevTransform.x ||
54538             currTransform.y !== prevTransform.y) {
54539
54540             var nodes = utilGetAllNodes(entityIDs, context.graph()),
54541                 points = nodes.map(function(n) { return projection$$1(n.loc); });
54542
54543             if (points.length === 1) {  // degenerate case
54544                 pivot = points[0];
54545             } else if (points.length === 2) {
54546                 pivot = geoInterp(points[0], points[1], 0.5);
54547             } else {
54548                 pivot = d3polygonCentroid(d3polygonHull(points));
54549             }
54550             prevAngle = undefined;
54551         }
54552
54553
54554         var currMouse = context.mouse(),
54555             currAngle = Math.atan2(currMouse[1] - pivot[1], currMouse[0] - pivot[0]);
54556
54557         if (typeof prevAngle === 'undefined') prevAngle = currAngle;
54558         var delta = currAngle - prevAngle;
54559
54560         fn(actionRotate(entityIDs, pivot, delta, projection$$1), annotation);
54561
54562         prevTransform = currTransform;
54563         prevAngle = currAngle;
54564         prevGraph = context.graph();
54565     }
54566
54567
54568     function finish() {
54569         event.stopPropagation();
54570         context.enter(modeSelect(context, entityIDs));
54571     }
54572
54573
54574     function cancel() {
54575         context.pop();
54576         context.enter(modeSelect(context, entityIDs));
54577     }
54578
54579
54580     function undone() {
54581         context.enter(modeBrowse(context));
54582     }
54583
54584
54585     mode.enter = function() {
54586         behaviors.forEach(function(behavior) {
54587             context.install(behavior);
54588         });
54589
54590         context.surface()
54591             .on('mousemove.rotate', doRotate)
54592             .on('click.rotate', finish);
54593
54594         context.history()
54595             .on('undone.rotate', undone);
54596
54597         keybinding
54598             .on('⎋', cancel)
54599             .on('↩', finish);
54600
54601         select(document)
54602             .call(keybinding);
54603     };
54604
54605
54606     mode.exit = function() {
54607         behaviors.forEach(function(behavior) {
54608             context.uninstall(behavior);
54609         });
54610
54611         context.surface()
54612             .on('mousemove.rotate', null)
54613             .on('click.rotate', null);
54614
54615         context.history()
54616             .on('undone.rotate', null);
54617
54618         keybinding.off();
54619     };
54620
54621
54622     return mode;
54623 }
54624
54625 function modeSave$$1(context) {
54626     var mode = {
54627         id: 'save'
54628     };
54629
54630     var keybinding = d3keybinding('select');
54631
54632     var commit = uiCommit(context)
54633         .on('cancel', cancel)
54634         .on('save', save);
54635
54636
54637     function cancel() {
54638         context.enter(modeBrowse(context));
54639     }
54640
54641
54642     function save(changeset, tryAgain) {
54643
54644         var osm = context.connection(),
54645             loading = uiLoading(context).message(t('save.uploading')).blocking(true),
54646             history = context.history(),
54647             origChanges = history.changes(actionDiscardTags(history.difference())),
54648             localGraph = context.graph(),
54649             remoteGraph = coreGraph$$1(history.base(), true),
54650             modified = lodash.filter(history.difference().summary(), {changeType: 'modified'}),
54651             toCheck = lodash.map(lodash.map(modified, 'entity'), 'id'),
54652             toLoad = withChildNodes(toCheck, localGraph),
54653             conflicts = [],
54654             errors = [];
54655
54656         if (!osm) return;
54657
54658         if (!tryAgain) {
54659             history.perform(actionNoop());  // checkpoint
54660         }
54661
54662         context.container().call(loading);
54663
54664         if (toCheck.length) {
54665             osm.loadMultiple(toLoad, loaded);
54666         } else {
54667             upload();
54668         }
54669
54670
54671         function withChildNodes(ids, graph) {
54672             return lodash.uniq(lodash.reduce(ids, function(result, id) {
54673                 var entity = graph.entity(id);
54674                 if (entity.type === 'way') {
54675                     try {
54676                         var cn = graph.childNodes(entity);
54677                         result.push.apply(result, lodash.map(lodash.filter(cn, 'version'), 'id'));
54678                     } catch (err) {
54679                         /* eslint-disable no-console */
54680                         if (typeof console !== 'undefined') console.error(err);
54681                         /* eslint-enable no-console */
54682                     }
54683                 }
54684                 return result;
54685             }, lodash.clone(ids)));
54686         }
54687
54688
54689         // Reload modified entities into an alternate graph and check for conflicts..
54690         function loaded(err, result) {
54691             if (errors.length) return;
54692
54693             if (err) {
54694                 errors.push({
54695                     msg: err.responseText,
54696                     details: [ t('save.status_code', { code: err.status }) ]
54697                 });
54698                 showErrors();
54699
54700             } else {
54701                 var loadMore = [];
54702                 lodash.each(result.data, function(entity) {
54703                     remoteGraph.replace(entity);
54704                     toLoad = lodash.without(toLoad, entity.id);
54705
54706                     // Because loadMultiple doesn't download /full like loadEntity,
54707                     // need to also load children that aren't already being checked..
54708                     if (!entity.visible) return;
54709                     if (entity.type === 'way') {
54710                         loadMore.push.apply(loadMore,
54711                             lodash.difference(entity.nodes, toCheck, toLoad, loadMore));
54712                     } else if (entity.type === 'relation' && entity.isMultipolygon()) {
54713                         loadMore.push.apply(loadMore,
54714                             lodash.difference(lodash.map(entity.members, 'id'), toCheck, toLoad, loadMore));
54715                     }
54716                 });
54717
54718                 if (loadMore.length) {
54719                     toLoad.push.apply(toLoad, loadMore);
54720                     osm.loadMultiple(loadMore, loaded);
54721                 }
54722
54723                 if (!toLoad.length) {
54724                     checkConflicts();
54725                 }
54726             }
54727         }
54728
54729
54730         function checkConflicts() {
54731             function choice(id, text$$1, action) {
54732                 return { id: id, text: text$$1, action: function() { history.replace(action); } };
54733             }
54734             function formatUser(d) {
54735                 return '<a href="' + osm.userURL(d) + '" target="_blank">' + d + '</a>';
54736             }
54737             function entityName(entity) {
54738                 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
54739             }
54740
54741             function compareVersions(local, remote) {
54742                 if (local.version !== remote.version) return false;
54743
54744                 if (local.type === 'way') {
54745                     var children = lodash.union(local.nodes, remote.nodes);
54746
54747                     for (var i = 0; i < children.length; i++) {
54748                         var a = localGraph.hasEntity(children[i]),
54749                             b = remoteGraph.hasEntity(children[i]);
54750
54751                         if (a && b && a.version !== b.version) return false;
54752                     }
54753                 }
54754
54755                 return true;
54756             }
54757
54758             lodash.each(toCheck, function(id) {
54759                 var local = localGraph.entity(id),
54760                     remote = remoteGraph.entity(id);
54761
54762                 if (compareVersions(local, remote)) return;
54763
54764                 var action = actionMergeRemoteChanges,
54765                     merge$$1 = action(id, localGraph, remoteGraph, formatUser);
54766
54767                 history.replace(merge$$1);
54768
54769                 var mergeConflicts = merge$$1.conflicts();
54770                 if (!mergeConflicts.length) return;  // merged safely
54771
54772                 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
54773                     forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote'),
54774                     keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore')),
54775                     keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
54776
54777                 conflicts.push({
54778                     id: id,
54779                     name: entityName(local),
54780                     details: mergeConflicts,
54781                     chosen: 1,
54782                     choices: [
54783                         choice(id, keepMine, forceLocal),
54784                         choice(id, keepTheirs, forceRemote)
54785                     ]
54786                 });
54787             });
54788
54789             upload();
54790         }
54791
54792
54793         function upload() {
54794             if (conflicts.length) {
54795                 conflicts.sort(function(a,b) { return b.id.localeCompare(a.id); });
54796                 showConflicts();
54797             } else if (errors.length) {
54798                 showErrors();
54799             } else {
54800                 var changes = history.changes(actionDiscardTags(history.difference()));
54801                 if (changes.modified.length || changes.created.length || changes.deleted.length) {
54802                     osm.putChangeset(changeset, changes, uploadCallback);
54803                 } else {        // changes were insignificant or reverted by user
54804                     select('.inspector-wrap *').remove();
54805                     loading.close();
54806                     context.flush();
54807                     cancel();
54808                 }
54809             }
54810         }
54811
54812
54813         function uploadCallback(err, changeset) {
54814             if (err) {
54815                 errors.push({
54816                     msg: err.responseText,
54817                     details: [ t('save.status_code', { code: err.status }) ]
54818                 });
54819                 showErrors();
54820             } else {
54821                 history.clearSaved();
54822                 success(changeset);
54823                 // Add delay to allow for postgres replication #1646 #2678
54824                 window.setTimeout(function() {
54825                     select('.inspector-wrap *').remove();
54826                     loading.close();
54827                     context.flush();
54828                 }, 2500);
54829             }
54830         }
54831
54832
54833         function showConflicts() {
54834             var selection$$1 = context.container()
54835                 .select('#sidebar')
54836                 .append('div')
54837                 .attr('class','sidebar-component');
54838
54839             loading.close();
54840
54841             selection$$1.call(uiConflicts(context)
54842                 .list(conflicts)
54843                 .on('download', function() {
54844                     var data = JXON.stringify(changeset.update({ id: 'CHANGEME' }).osmChangeJXON(origChanges)),
54845                         win = window.open('data:text/xml,' + encodeURIComponent(data), '_blank');
54846                     win.focus();
54847                 })
54848                 .on('cancel', function() {
54849                     history.pop();
54850                     selection$$1.remove();
54851                 })
54852                 .on('save', function() {
54853                     for (var i = 0; i < conflicts.length; i++) {
54854                         if (conflicts[i].chosen === 1) {  // user chose "keep theirs"
54855                             var entity = context.hasEntity(conflicts[i].id);
54856                             if (entity && entity.type === 'way') {
54857                                 var children = lodash.uniq(entity.nodes);
54858                                 for (var j = 0; j < children.length; j++) {
54859                                     history.replace(actionRevert(children[j]));
54860                                 }
54861                             }
54862                             history.replace(actionRevert(conflicts[i].id));
54863                         }
54864                     }
54865
54866                     selection$$1.remove();
54867                     save(changeset, true);
54868                 })
54869             );
54870         }
54871
54872
54873         function showErrors() {
54874             var selection$$1 = uiConfirm(context.container());
54875
54876             history.pop();
54877             loading.close();
54878
54879             selection$$1
54880                 .select('.modal-section.header')
54881                 .append('h3')
54882                 .text(t('save.error'));
54883
54884             addErrors(selection$$1, errors);
54885             selection$$1.okButton();
54886         }
54887
54888
54889         function addErrors(selection$$1, data) {
54890             var message = selection$$1
54891                 .select('.modal-section.message-text');
54892
54893             var items = message
54894                 .selectAll('.error-container')
54895                 .data(data);
54896
54897             var enter = items.enter()
54898                 .append('div')
54899                 .attr('class', 'error-container');
54900
54901             enter
54902                 .append('a')
54903                 .attr('class', 'error-description')
54904                 .attr('href', '#')
54905                 .classed('hide-toggle', true)
54906                 .text(function(d) { return d.msg || t('save.unknown_error_details'); })
54907                 .on('click', function() {
54908                     var error = select(this),
54909                         detail = select(this.nextElementSibling),
54910                         exp = error.classed('expanded');
54911
54912                     detail.style('display', exp ? 'none' : 'block');
54913                     error.classed('expanded', !exp);
54914
54915                     event.preventDefault();
54916                 });
54917
54918             var details = enter
54919                 .append('div')
54920                 .attr('class', 'error-detail-container')
54921                 .style('display', 'none');
54922
54923             details
54924                 .append('ul')
54925                 .attr('class', 'error-detail-list')
54926                 .selectAll('li')
54927                 .data(function(d) { return d.details || []; })
54928                 .enter()
54929                 .append('li')
54930                 .attr('class', 'error-detail-item')
54931                 .text(function(d) { return d; });
54932
54933             items.exit()
54934                 .remove();
54935         }
54936
54937     }
54938
54939
54940     function success(changeset) {
54941         commit.reset();
54942         context.enter(modeBrowse(context)
54943             .sidebar(uiSuccess(context)
54944                 .changeset(changeset)
54945                 .on('cancel', function() {
54946                     context.ui().sidebar.hide();
54947                 })
54948             )
54949         );
54950     }
54951
54952
54953     mode.enter = function() {
54954         function done() {
54955             context.ui().sidebar.show(commit);
54956         }
54957
54958         keybinding
54959             .on('⎋', cancel, true);
54960
54961         select(document)
54962             .call(keybinding);
54963
54964         context.container().selectAll('#content')
54965             .attr('class', 'inactive');
54966
54967         var osm = context.connection();
54968         if (!osm) return;
54969
54970         if (osm.authenticated()) {
54971             done();
54972         } else {
54973             osm.authenticate(function(err) {
54974                 if (err) {
54975                     cancel();
54976                 } else {
54977                     done();
54978                 }
54979             });
54980         }
54981     };
54982
54983
54984     mode.exit = function() {
54985         keybinding.off();
54986
54987         context.container().selectAll('#content')
54988             .attr('class', 'active');
54989
54990         context.ui().sidebar.hide();
54991     };
54992
54993     return mode;
54994 }
54995
54996 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
54997 // For example, ⌘Z -> Ctrl+Z
54998 var uiCmd = function (code) {
54999     var detected = utilDetect();
55000
55001     if (detected.os === 'mac') {
55002         return code;
55003     }
55004
55005     if (detected.os === 'win') {
55006         if (code === '⌘⇧Z') return 'Ctrl+Y';
55007     }
55008
55009     var result = '',
55010         replacements = {
55011             '⌘': 'Ctrl',
55012             '⇧': 'Shift',
55013             '⌥': 'Alt',
55014             '⌫': 'Backspace',
55015             '⌦': 'Delete'
55016         };
55017
55018     for (var i = 0; i < code.length; i++) {
55019         if (code[i] in replacements) {
55020             result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
55021         } else {
55022             result += code[i];
55023         }
55024     }
55025
55026     return result;
55027 };
55028
55029
55030 // return a display-focused string for a given keyboard code
55031 uiCmd.display = function(code) {
55032     if (code.length !== 1) return code;
55033
55034     var detected = utilDetect();
55035     var mac = (detected.os === 'mac');
55036     var replacements = {
55037         '⌘': mac ? '⌘ ' + t('shortcuts.key.cmd')    : t('shortcuts.key.ctrl'),
55038         '⇧': mac ? '⇧ ' + t('shortcuts.key.shift')  : t('shortcuts.key.shift'),
55039         '⌥': mac ? '⌥ ' + t('shortcuts.key.option') : t('shortcuts.key.alt'),
55040         '⌃': mac ? '⌃ ' + t('shortcuts.key.ctrl')   : t('shortcuts.key.ctrl'),
55041         '⌫': mac ? '⌫ ' + t('shortcuts.key.delete') : t('shortcuts.key.backspace'),
55042         '⌦': mac ? '⌦ ' + t('shortcuts.key.del')    : t('shortcuts.key.del'),
55043         '↖': mac ? '↖ ' + t('shortcuts.key.pgup')   : t('shortcuts.key.pgup'),
55044         '↘': mac ? '↘ ' + t('shortcuts.key.pgdn')   : t('shortcuts.key.pgdn'),
55045         '⇞': mac ? '⇞ ' + t('shortcuts.key.home')   : t('shortcuts.key.home'),
55046         '⇟': mac ? '⇟ ' + t('shortcuts.key.end')    : t('shortcuts.key.end'),
55047         '↵': mac ? '↵ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'),
55048         '⎋': mac ? '⎋ ' + t('shortcuts.key.esc')    : t('shortcuts.key.esc'),
55049     };
55050
55051     return replacements[code] || code;
55052 };
55053
55054 // deprecation warning - Radial Menu to be removed in iD v3
55055 var relatedParent;
55056
55057
55058 function modeSelect(context, selectedIDs) {
55059     var mode = {
55060         id: 'select',
55061         button: 'browse'
55062     };
55063
55064     var keybinding = d3keybinding('select'),
55065         timeout = null,
55066         behaviors = [
55067             behaviorCopy(context),
55068             behaviorPaste(context),
55069             behaviorBreathe(context),
55070             behaviorHover(context),
55071             behaviorSelect(context),
55072             behaviorLasso(context),
55073             modeDragNode$$1(context).selectedIDs(selectedIDs).behavior
55074         ],
55075         inspector,
55076         editMenu,
55077         newFeature = false,
55078         suppressMenu = true,
55079         follow = false;
55080
55081
55082     var wrap = context.container()
55083         .select('.inspector-wrap');
55084
55085
55086     function singular() {
55087         if (selectedIDs.length === 1) {
55088             return context.hasEntity(selectedIDs[0]);
55089         }
55090     }
55091
55092
55093     function checkSelectedIDs() {
55094         var ids = [];
55095         if (Array.isArray(selectedIDs)) {
55096             ids = selectedIDs.filter(function(id) {
55097                 return context.hasEntity(id);
55098             });
55099         }
55100
55101         if (ids.length) {
55102             selectedIDs = ids;
55103         } else {
55104             context.enter(modeBrowse(context));
55105         }
55106         return !!ids.length;
55107     }
55108
55109
55110     // find the common parent ways for nextVertex, previousVertex
55111     function commonParents() {
55112         var graph = context.graph(),
55113             commonParents = [];
55114
55115         for (var i = 0; i < selectedIDs.length; i++) {
55116             var entity = context.hasEntity(selectedIDs[i]);
55117             if (!entity || entity.geometry(graph) !== 'vertex') {
55118                 return [];  // selection includes some not vertexes
55119             }
55120
55121             var currParents = lodash.map(graph.parentWays(entity), 'id');
55122             if (!commonParents.length) {
55123                 commonParents = currParents;
55124                 continue;
55125             }
55126
55127             commonParents = lodash.intersection(commonParents, currParents);
55128             if (!commonParents.length) {
55129                 return [];
55130             }
55131         }
55132
55133         return commonParents;
55134     }
55135
55136
55137     function singularParent() {
55138         var parents = commonParents();
55139         if (!parents || parents.length === 0) {
55140             relatedParent = null;
55141             return null;
55142         }
55143
55144         // relatedParent is used when we visit a vertex with multiple
55145         // parents, and we want to remember which parent line we started on.
55146
55147         if (parents.length === 1) {
55148             relatedParent = parents[0];  // remember this parent for later
55149             return relatedParent;
55150         }
55151
55152         if (parents.indexOf(relatedParent) !== -1) {
55153             return relatedParent;   // prefer the previously seen parent
55154         }
55155
55156         return parents[0];
55157     }
55158
55159
55160     function closeMenu() {
55161         if (editMenu) {
55162             context.surface().call(editMenu.close);
55163         }
55164     }
55165
55166
55167     function positionMenu() {
55168         if (!editMenu) { return; }
55169
55170         var entity = singular();
55171         if (entity && context.geometry(entity.id) === 'relation') {
55172             suppressMenu = true;
55173         } else {
55174             var point = context.mouse(),
55175                 viewport = geoExtent$$1(context.projection.clipExtent()).polygon();
55176
55177             if (point && geoPointInPolygon(point, viewport)) {
55178                 editMenu.center(point);
55179             } else {
55180                 suppressMenu = true;
55181             }
55182         }
55183     }
55184
55185
55186     function showMenu() {
55187         closeMenu();
55188         if (editMenu) {
55189             context.surface().call(editMenu);
55190         }
55191     }
55192
55193
55194     function toggleMenu() {
55195         // deprecation warning - Radial Menu to be removed in iD v3
55196         if (select('.edit-menu, .radial-menu').empty()) {
55197             positionMenu();
55198             showMenu();
55199         } else {
55200             closeMenu();
55201         }
55202     }
55203
55204
55205     mode.selectedIDs = function() {
55206         return selectedIDs;
55207     };
55208
55209
55210     mode.reselect = function() {
55211         if (!checkSelectedIDs()) return;
55212
55213         var surfaceNode = context.surface().node();
55214         if (surfaceNode.focus) {   // FF doesn't support it
55215             surfaceNode.focus();
55216         }
55217
55218         positionMenu();
55219         if (!suppressMenu) {
55220             showMenu();
55221         }
55222     };
55223
55224
55225     mode.newFeature = function(_) {
55226         if (!arguments.length) return newFeature;
55227         newFeature = _;
55228         return mode;
55229     };
55230
55231
55232     mode.suppressMenu = function(_) {
55233         if (!arguments.length) return suppressMenu;
55234         suppressMenu = _;
55235         return mode;
55236     };
55237
55238
55239     mode.follow = function(_) {
55240         if (!arguments.length) return follow;
55241         follow = _;
55242         return mode;
55243     };
55244
55245
55246     mode.enter = function() {
55247
55248         function update() {
55249             closeMenu();
55250             checkSelectedIDs();
55251         }
55252
55253
55254         function dblclick() {
55255             var target = select(event.target),
55256                 datum = target.datum();
55257
55258             if (datum instanceof osmWay && !target.classed('fill')) {
55259                 var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
55260                     prev = datum.nodes[choice.index - 1],
55261                     next = datum.nodes[choice.index];
55262
55263                 context.perform(
55264                     actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
55265                     t('operations.add.annotation.vertex')
55266                 );
55267
55268                 event.preventDefault();
55269                 event.stopPropagation();
55270
55271             } else if (datum.type === 'midpoint') {
55272                 context.perform(
55273                     actionAddMidpoint({loc: datum.loc, edge: datum.edge}, osmNode()),
55274                     t('operations.add.annotation.vertex'));
55275
55276                 event.preventDefault();
55277                 event.stopPropagation();
55278             }
55279         }
55280
55281
55282         function selectElements(drawn) {
55283             if (!checkSelectedIDs()) return;
55284
55285             var surface = context.surface(),
55286                 entity = singular();
55287
55288             if (entity && context.geometry(entity.id) === 'relation') {
55289                 suppressMenu = true;
55290                 return;
55291             }
55292
55293             surface.selectAll('.related')
55294                 .classed('related', false);
55295
55296             singularParent();
55297             if (relatedParent) {
55298                 surface.selectAll(utilEntitySelector([relatedParent]))
55299                     .classed('related', true);
55300             }
55301
55302             var selection$$1 = context.surface()
55303                 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
55304
55305             if (selection$$1.empty()) {
55306                 // Return to browse mode if selected DOM elements have
55307                 // disappeared because the user moved them out of view..
55308                 var source = event && event.type === 'zoom' && event.sourceEvent;
55309                 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
55310                     context.enter(modeBrowse(context));
55311                 }
55312             } else {
55313                 selection$$1
55314                     .classed('selected', true);
55315             }
55316         }
55317
55318
55319         function esc() {
55320             context.enter(modeBrowse(context));
55321         }
55322
55323
55324         function firstVertex() {
55325             event.preventDefault();
55326             var parent = singularParent();
55327             if (parent) {
55328                 var way = context.entity(parent);
55329                 context.enter(
55330                     modeSelect(context, [way.first()]).follow(true)
55331                 );
55332             }
55333         }
55334
55335
55336         function lastVertex() {
55337             event.preventDefault();
55338             var parent = singularParent();
55339             if (parent) {
55340                 var way = context.entity(parent);
55341                 context.enter(
55342                     modeSelect(context, [way.last()]).follow(true)
55343                 );
55344             }
55345         }
55346
55347
55348         function previousVertex() {
55349             event.preventDefault();
55350             var parent = singularParent();
55351             if (!parent) return;
55352
55353             var way = context.entity(parent),
55354                 length = way.nodes.length,
55355                 curr = way.nodes.indexOf(selectedIDs[0]),
55356                 index = -1;
55357
55358             if (curr > 0) {
55359                 index = curr - 1;
55360             } else if (way.isClosed()) {
55361                 index = length - 2;
55362             }
55363
55364             if (index !== -1) {
55365                 context.enter(
55366                     modeSelect(context, [way.nodes[index]]).follow(true)
55367                 );
55368             }
55369         }
55370
55371
55372         function nextVertex() {
55373             event.preventDefault();
55374             var parent = singularParent();
55375             if (!parent) return;
55376
55377             var way = context.entity(parent),
55378                 length = way.nodes.length,
55379                 curr = way.nodes.indexOf(selectedIDs[0]),
55380                 index = -1;
55381
55382             if (curr < length - 1) {
55383                 index = curr + 1;
55384             } else if (way.isClosed()) {
55385                 index = 0;
55386             }
55387
55388             if (index !== -1) {
55389                 context.enter(
55390                     modeSelect(context, [way.nodes[index]]).follow(true)
55391                 );
55392             }
55393         }
55394
55395
55396         function nextParent() {
55397             event.preventDefault();
55398             var parents = lodash.uniq(commonParents());
55399             if (!parents || parents.length < 2) return;
55400
55401             var index = parents.indexOf(relatedParent);
55402             if (index < 0 || index > parents.length - 2) {
55403                 relatedParent = parents[0];
55404             } else {
55405                 relatedParent = parents[index + 1];
55406             }
55407
55408             var surface = context.surface();
55409             surface.selectAll('.related')
55410                 .classed('related', false);
55411
55412             if (relatedParent) {
55413                 surface.selectAll(utilEntitySelector([relatedParent]))
55414                     .classed('related', true);
55415             }
55416         }
55417
55418
55419         if (!checkSelectedIDs()) return;
55420
55421         var operations = lodash.without(values(Operations), operationDelete)
55422                 .map(function(o) { return o(selectedIDs, context); })
55423                 .filter(function(o) { return o.available(); });
55424
55425         // deprecation warning - Radial Menu to be removed in iD v3
55426         var isRadialMenu = context.storage('edit-menu-style') === 'radial';
55427         if (isRadialMenu) {
55428             operations = operations.slice(0,7);
55429             operations.unshift(operationDelete(selectedIDs, context));
55430         } else {
55431             operations.push(operationDelete(selectedIDs, context));
55432         }
55433
55434         operations.forEach(function(operation) {
55435             if (operation.behavior) {
55436                 behaviors.push(operation.behavior);
55437             }
55438         });
55439
55440         behaviors.forEach(function(behavior) {
55441             context.install(behavior);
55442         });
55443
55444         keybinding
55445             .on(['[', 'pgup'], previousVertex)
55446             .on([']', 'pgdown'], nextVertex)
55447             .on(['{', uiCmd('⌘['), 'home'], firstVertex)
55448             .on(['}', uiCmd('⌘]'), 'end'], lastVertex)
55449             .on(['\\', 'pause'], nextParent)
55450             .on('⎋', esc, true)
55451             .on('space', toggleMenu);
55452
55453         select(document)
55454             .call(keybinding);
55455
55456
55457         // deprecation warning - Radial Menu to be removed in iD v3
55458         editMenu = isRadialMenu
55459             ? uiRadialMenu(context, operations)
55460             : uiEditMenu(context, operations);
55461
55462         context.ui().sidebar
55463             .select(singular() ? singular().id : null, newFeature);
55464
55465         context.history()
55466             .on('undone.select', update)
55467             .on('redone.select', update);
55468
55469         context.map()
55470             .on('move.select', closeMenu)
55471             .on('drawn.select', selectElements);
55472
55473         context.surface()
55474             .on('dblclick.select', dblclick);
55475
55476
55477         selectElements();
55478
55479         if (selectedIDs.length > 1) {
55480             var entities = uiSelectionList(context, selectedIDs);
55481             context.ui().sidebar.show(entities);
55482         }
55483
55484         if (follow) {
55485             var extent$$1 = geoExtent$$1(),
55486                 graph = context.graph();
55487             selectedIDs.forEach(function(id) {
55488                 var entity = context.entity(id);
55489                 extent$$1._extend(entity.extent(graph));
55490             });
55491
55492             var loc = extent$$1.center();
55493             context.map().centerEase(loc);
55494         } else if (singular() && singular().type === 'way') {
55495             context.map().pan([0,0]);  // full redraw, to adjust z-sorting #2914
55496         }
55497
55498         timeout = window.setTimeout(function() {
55499             positionMenu();
55500             if (!suppressMenu) {
55501                 showMenu();
55502             }
55503         }, 270);  /* after any centerEase completes */
55504
55505     };
55506
55507
55508     mode.exit = function() {
55509         if (timeout) window.clearTimeout(timeout);
55510
55511         if (inspector) wrap.call(inspector.close);
55512
55513         behaviors.forEach(function(behavior) {
55514             context.uninstall(behavior);
55515         });
55516
55517         keybinding.off();
55518         closeMenu();
55519         editMenu = undefined;
55520
55521         context.history()
55522             .on('undone.select', null)
55523             .on('redone.select', null);
55524
55525         var surface = context.surface();
55526
55527         surface
55528             .on('dblclick.select', null);
55529
55530         surface
55531             .selectAll('.selected')
55532             .classed('selected', false);
55533
55534         surface
55535             .selectAll('.related')
55536             .classed('related', false);
55537
55538         context.map().on('drawn.select', null);
55539         context.ui().sidebar.hide();
55540     };
55541
55542
55543     return mode;
55544 }
55545
55546 function uiAccount(context) {
55547     var osm = context.connection();
55548
55549
55550     function update(selection$$1) {
55551         if (!osm) return;
55552
55553         if (!osm.authenticated()) {
55554             selection$$1.selectAll('#userLink, #logoutLink')
55555                 .classed('hide', true);
55556             return;
55557         }
55558
55559         osm.userDetails(function(err, details) {
55560             var userLink = selection$$1.select('#userLink'),
55561                 logoutLink = selection$$1.select('#logoutLink');
55562
55563             userLink.html('');
55564             logoutLink.html('');
55565
55566             if (err) return;
55567
55568             selection$$1.selectAll('#userLink, #logoutLink')
55569                 .classed('hide', false);
55570
55571             // Link
55572             userLink.append('a')
55573                 .attr('href', osm.userURL(details.display_name))
55574                 .attr('target', '_blank');
55575
55576             // Add thumbnail or dont
55577             if (details.image_url) {
55578                 userLink.append('img')
55579                     .attr('class', 'icon pre-text user-icon')
55580                     .attr('src', details.image_url);
55581             } else {
55582                 userLink
55583                     .call(svgIcon('#icon-avatar', 'pre-text light'));
55584             }
55585
55586             // Add user name
55587             userLink.append('span')
55588                 .attr('class', 'label')
55589                 .text(details.display_name);
55590
55591             logoutLink.append('a')
55592                 .attr('class', 'logout')
55593                 .attr('href', '#')
55594                 .text(t('logout'))
55595                 .on('click.logout', function() {
55596                     event.preventDefault();
55597                     osm.logout();
55598                 });
55599         });
55600     }
55601
55602
55603     return function(selection$$1) {
55604         selection$$1.append('li')
55605             .attr('id', 'logoutLink')
55606             .classed('hide', true);
55607
55608         selection$$1.append('li')
55609             .attr('id', 'userLink')
55610             .classed('hide', true);
55611
55612         if (osm) {
55613             osm.on('change.account', function() { update(selection$$1); });
55614             update(selection$$1);
55615         }
55616     };
55617 }
55618
55619 function uiAttribution(context) {
55620     var selection$$1;
55621
55622
55623     function attribution(data, klass) {
55624         var div = selection$$1.selectAll('.' + klass)
55625             .data([0]);
55626
55627         div = div.enter()
55628             .append('div')
55629             .attr('class', klass)
55630             .merge(div);
55631
55632
55633         var background = div.selectAll('.attribution')
55634             .data(data, function(d) { return d.name(); });
55635
55636         background.exit()
55637             .remove();
55638
55639         background = background.enter()
55640             .append('span')
55641             .attr('class', 'attribution')
55642             .each(function(d) {
55643                 if (d.terms_html) {
55644                     select(this)
55645                         .html(d.terms_html);
55646                     return;
55647                 }
55648
55649                 var selection$$1;
55650                 if (d.terms_url) {
55651                     selection$$1 = select(this)
55652                         .append('a')
55653                         .attr('href', d.terms_url)
55654                         .attr('target', '_blank');
55655                 } else {
55656                     selection$$1 = select(this);
55657                 }
55658
55659
55660                 var id_safe = d.id.replace('.', '<TX_DOT>');
55661                 var terms_text = t('imagery.' + id_safe + '.attribution.text',
55662                     { default: d.terms_text || d.id || d.name() }
55663                 );
55664
55665                 if (d.icon && !d.overlay) {
55666                     selection$$1
55667                         .append('img')
55668                         .attr('class', 'source-image')
55669                         .attr('src', d.icon);
55670                 }
55671
55672                 selection$$1
55673                     .append('span')
55674                     .attr('class', 'attribution-text')
55675                     .text(terms_text);
55676             })
55677             .merge(background);
55678
55679
55680         var copyright = background.selectAll('.copyright-notice')
55681             .data(function(d) {
55682                 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
55683                 return notice ? [notice] : [];
55684             });
55685
55686         copyright.exit()
55687             .remove();
55688
55689         copyright = copyright.enter()
55690             .append('span')
55691             .attr('class', 'copyright-notice')
55692             .merge(copyright);
55693
55694         copyright
55695             .text(String);
55696     }
55697
55698
55699     function update() {
55700         attribution([context.background().baseLayerSource()], 'base-layer-attribution');
55701         attribution(context.background().overlayLayerSources().filter(function (s) {
55702             return s.validZoom(context.map().zoom());
55703         }), 'overlay-layer-attribution');
55704     }
55705
55706
55707     return function(select$$1) {
55708         selection$$1 = select$$1;
55709
55710         context.background()
55711             .on('change.attribution', update);
55712
55713         context.map()
55714             .on('move.attribution', lodash.throttle(update, 400, {leading: false}));
55715
55716         update();
55717     };
55718 }
55719
55720 function localeDateString(s) {
55721     if (!s) return null;
55722     var d = new Date(s);
55723     if (isNaN(d.getTime())) return null;
55724     return d.toLocaleDateString();
55725 }
55726
55727 function vintageRange(vintage) {
55728     var s;
55729     if (vintage.start || vintage.end) {
55730         s = (vintage.start || '?');
55731         if (vintage.start !== vintage.end) {
55732             s += ' - ' + (vintage.end || '?');
55733         }
55734     }
55735     return s;
55736 }
55737
55738
55739 function rendererBackgroundSource(data) {
55740     var source = lodash.clone(data),
55741         offset = [0, 0],
55742         name = source.name,
55743         description = source.description,
55744         best = !!source.best,
55745         template = source.template;
55746
55747     source.scaleExtent = data.scaleExtent || [0, 20];
55748     source.overzoom = data.overzoom !== false;
55749
55750
55751     source.offset = function(_) {
55752         if (!arguments.length) return offset;
55753         offset = _;
55754         return source;
55755     };
55756
55757
55758     source.nudge = function(_, zoomlevel) {
55759         offset[0] += _[0] / Math.pow(2, zoomlevel);
55760         offset[1] += _[1] / Math.pow(2, zoomlevel);
55761         return source;
55762     };
55763
55764
55765     source.name = function() {
55766         var id_safe = source.id.replace('.', '<TX_DOT>');
55767         return t('imagery.' + id_safe + '.name', { default: name });
55768     };
55769
55770
55771     source.description = function() {
55772         var id_safe = source.id.replace('.', '<TX_DOT>');
55773         return t('imagery.' + id_safe + '.description', { default: description });
55774     };
55775
55776
55777     source.best = function() {
55778         return best;
55779     };
55780
55781
55782     source.area = function() {
55783         if (!data.polygon) return Number.MAX_VALUE;  // worldwide
55784         var area$$1 = area({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
55785         return isNaN(area$$1) ? 0 : area$$1;
55786     };
55787
55788
55789     source.imageryUsed = function() {
55790         return name || source.id;
55791     };
55792
55793
55794     source.template = function(_) {
55795         if (!arguments.length) return template;
55796         if (source.id === 'custom') template = _;
55797         return source;
55798     };
55799
55800
55801     source.url = function(coord) {
55802         return template
55803             .replace('{x}', coord[0])
55804             .replace('{y}', coord[1])
55805             // TMS-flipped y coordinate
55806             .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
55807             .replace(/\{z(oom)?\}/, coord[2])
55808             .replace(/\{switch:([^}]+)\}/, function(s, r) {
55809                 var subdomains = r.split(',');
55810                 return subdomains[(coord[0] + coord[1]) % subdomains.length];
55811             })
55812             .replace('{u}', function() {
55813                 var u = '';
55814                 for (var zoom$$1 = coord[2]; zoom$$1 > 0; zoom$$1--) {
55815                     var b = 0;
55816                     var mask = 1 << (zoom$$1 - 1);
55817                     if ((coord[0] & mask) !== 0) b++;
55818                     if ((coord[1] & mask) !== 0) b += 2;
55819                     u += b.toString();
55820                 }
55821                 return u;
55822             });
55823     };
55824
55825
55826     source.intersects = function(extent$$1) {
55827         extent$$1 = extent$$1.polygon();
55828         return !data.polygon || data.polygon.some(function(polygon) {
55829             return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
55830         });
55831     };
55832
55833
55834     source.validZoom = function(z) {
55835         return source.scaleExtent[0] <= z &&
55836             (source.overzoom || source.scaleExtent[1] > z);
55837     };
55838
55839
55840     source.isLocatorOverlay = function() {
55841         return source.id === 'mapbox_locator_overlay';
55842     };
55843
55844
55845     source.copyrightNotices = function() {};
55846
55847
55848     source.getVintage = function(center, tileCoord, callback) {
55849         var vintage = {
55850             start: localeDateString(source.startDate),
55851             end: localeDateString(source.endDate)
55852         };
55853         vintage.range = vintageRange(vintage);
55854         callback(null, vintage);
55855     };
55856
55857
55858     return source;
55859 }
55860
55861
55862 rendererBackgroundSource.Bing = function(data, dispatch$$1) {
55863     // http://msdn.microsoft.com/en-us/library/ff701716.aspx
55864     // http://msdn.microsoft.com/en-us/library/ff701701.aspx
55865
55866     data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
55867
55868     var bing = rendererBackgroundSource(data),
55869         key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
55870         url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
55871             key + '&jsonp={callback}',
55872         cache = {},
55873         providers = [];
55874
55875     jsonpRequest(url, function(json$$1) {
55876         providers = json$$1.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
55877             return {
55878                 attribution: provider.attribution,
55879                 areas: provider.coverageAreas.map(function(area$$1) {
55880                     return {
55881                         zoom: [area$$1.zoomMin, area$$1.zoomMax],
55882                         extent: geoExtent$$1([area$$1.bbox[1], area$$1.bbox[0]], [area$$1.bbox[3], area$$1.bbox[2]])
55883                     };
55884                 })
55885             };
55886         });
55887         dispatch$$1.call('change');
55888     });
55889
55890
55891     bing.copyrightNotices = function(zoom$$1, extent$$1) {
55892         zoom$$1 = Math.min(zoom$$1, 21);
55893         return providers.filter(function(provider) {
55894             return lodash.some(provider.areas, function(area$$1) {
55895                 return extent$$1.intersects(area$$1.extent) &&
55896                     area$$1.zoom[0] <= zoom$$1 &&
55897                     area$$1.zoom[1] >= zoom$$1;
55898             });
55899         }).map(function(provider) {
55900             return provider.attribution;
55901         }).join(', ');
55902     };
55903
55904
55905     bing.getVintage = function(center, tileCoord, callback) {
55906         var tileId = tileCoord.slice(0, 3).join('/'),
55907             zoom$$1 = Math.min(tileCoord[2], 21),
55908             centerPoint = center[1] + ',' + center[0],  // lat,lng
55909             url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
55910                 '?zl=' + zoom$$1 + '&key=' + key + '&jsonp={callback}';
55911
55912         if (!cache[tileId]) {
55913             cache[tileId] = {};
55914         }
55915         if (cache[tileId] && cache[tileId].vintage) {
55916             return callback(null, cache[tileId].vintage);
55917         }
55918
55919         jsonpRequest(url, function(result) {
55920             var err = (!result && 'Unknown Error') || result.errorDetails;
55921             if (err) {
55922                 return callback(err);
55923             } else {
55924                 var vintage = {
55925                     start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
55926                     end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
55927                 };
55928                 vintage.range = vintageRange(vintage);
55929                 cache[tileId].vintage = vintage;
55930                 return callback(null, vintage);
55931             }
55932         });
55933     };
55934
55935
55936     bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
55937
55938
55939     return bing;
55940 };
55941
55942
55943 rendererBackgroundSource.None = function() {
55944     var source = rendererBackgroundSource({ id: 'none', template: '' });
55945
55946
55947     source.name = function() {
55948         return t('background.none');
55949     };
55950
55951
55952     source.imageryUsed = function() {
55953         return 'None';
55954     };
55955
55956
55957     source.area = function() {
55958         return -1;  // sources in background pane are sorted by area
55959     };
55960
55961
55962     return source;
55963 };
55964
55965
55966 rendererBackgroundSource.Custom = function(template) {
55967     var source = rendererBackgroundSource({ id: 'custom', template: template });
55968
55969
55970     source.name = function() {
55971         return t('background.custom');
55972     };
55973
55974
55975     source.imageryUsed = function() {
55976         return 'Custom (' + source.template() + ')';
55977     };
55978
55979
55980     source.area = function() {
55981         return -2;  // sources in background pane are sorted by area
55982     };
55983
55984
55985     return source;
55986 };
55987
55988 function rendererTileLayer(context) {
55989     var tileSize = 256,
55990         geotile = d3geoTile(),
55991         projection$$1,
55992         cache = {},
55993         tileOrigin,
55994         z,
55995         transformProp = utilPrefixCSSProperty('Transform'),
55996         source;
55997
55998
55999     // blacklist overlay tiles around Null Island..
56000     function nearNullIsland(x, y, z) {
56001         if (z >= 7) {
56002             var center = Math.pow(2, z - 1),
56003                 width = Math.pow(2, z - 6),
56004                 min$$1 = center - (width / 2),
56005                 max$$1 = center + (width / 2) - 1;
56006             return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
56007         }
56008         return false;
56009     }
56010
56011
56012     function tileSizeAtZoom(d, z) {
56013         var epsilon = 0.002;
56014         return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + epsilon;
56015     }
56016
56017
56018     function atZoom(t$$1, distance$$1) {
56019         var power = Math.pow(2, distance$$1);
56020         return [
56021             Math.floor(t$$1[0] * power),
56022             Math.floor(t$$1[1] * power),
56023             t$$1[2] + distance$$1
56024         ];
56025     }
56026
56027
56028     function lookUp(d) {
56029         for (var up = -1; up > -d[2]; up--) {
56030             var tile = atZoom(d, up);
56031             if (cache[source.url(tile)] !== false) {
56032                 return tile;
56033             }
56034         }
56035     }
56036
56037
56038     function uniqueBy(a, n) {
56039         var o = [], seen = {};
56040         for (var i = 0; i < a.length; i++) {
56041             if (seen[a[i][n]] === undefined) {
56042                 o.push(a[i]);
56043                 seen[a[i][n]] = true;
56044             }
56045         }
56046         return o;
56047     }
56048
56049
56050     function addSource(d) {
56051         d.push(source.url(d));
56052         return d;
56053     }
56054
56055
56056     // Update tiles based on current state of `projection`.
56057     function background(selection$$1) {
56058         z = Math.max(Math.log(projection$$1.scale() * 2 * Math.PI) / Math.log(2) - 8, 0);
56059
56060         var pixelOffset;
56061         if (source) {
56062             pixelOffset = [
56063                 source.offset()[0] * Math.pow(2, z),
56064                 source.offset()[1] * Math.pow(2, z)
56065             ];
56066         } else {
56067             pixelOffset = [0, 0];
56068         }
56069
56070         var translate = [
56071             projection$$1.translate()[0] + pixelOffset[0],
56072             projection$$1.translate()[1] + pixelOffset[1]
56073         ];
56074
56075         geotile
56076             .scale(projection$$1.scale() * 2 * Math.PI)
56077             .translate(translate);
56078
56079         tileOrigin = [
56080             projection$$1.scale() * Math.PI - translate[0],
56081             projection$$1.scale() * Math.PI - translate[1]
56082         ];
56083
56084         render(selection$$1);
56085     }
56086
56087
56088     // Derive the tiles onscreen, remove those offscreen and position them.
56089     // Important that this part not depend on `projection` because it's
56090     // rentered when tiles load/error (see #644).
56091     function render(selection$$1) {
56092         if (!source) return;
56093         var requests = [];
56094         var showDebug = context.getDebug('tile') && !source.overlay;
56095
56096         if (source.validZoom(z)) {
56097             geotile().forEach(function(d) {
56098                 addSource(d);
56099                 if (d[3] === '') return;
56100                 if (typeof d[3] !== 'string') return; // Workaround for #2295
56101                 requests.push(d);
56102                 if (cache[d[3]] === false && lookUp(d)) {
56103                     requests.push(addSource(lookUp(d)));
56104                 }
56105             });
56106
56107             requests = uniqueBy(requests, 3).filter(function(r) {
56108                 if (!!source.overlay && nearNullIsland(r[0], r[1], r[2])) {
56109                     return false;
56110                 }
56111                 // don't re-request tiles which have failed in the past
56112                 return cache[r[3]] !== false;
56113             });
56114         }
56115
56116
56117         function load(d) {
56118             cache[d[3]] = true;
56119             select(this)
56120                 .on('error', null)
56121                 .on('load', null)
56122                 .classed('tile-loaded', true);
56123             render(selection$$1);
56124         }
56125
56126         function error(d) {
56127             cache[d[3]] = false;
56128             select(this)
56129                 .on('error', null)
56130                 .on('load', null)
56131                 .remove();
56132             render(selection$$1);
56133         }
56134
56135         function imageTransform(d) {
56136             var _ts = tileSize * Math.pow(2, z - d[2]);
56137             var scale = tileSizeAtZoom(d, z);
56138             return 'translate(' +
56139                 ((d[0] * _ts) - tileOrigin[0]) + 'px,' +
56140                 ((d[1] * _ts) - tileOrigin[1]) + 'px) ' +
56141                 'scale(' + scale + ',' + scale + ')';
56142         }
56143
56144         function tileCenter(d) {
56145             var _ts = tileSize * Math.pow(2, z - d[2]);
56146             return [
56147                 ((d[0] * _ts) - tileOrigin[0] + (_ts / 2)),
56148                 ((d[1] * _ts) - tileOrigin[1] + (_ts / 2))
56149             ];
56150         }
56151
56152         function debugTransform(d) {
56153             var coord = tileCenter(d);
56154             return 'translate(' + coord[0] + 'px,' + coord[1] + 'px)';
56155         }
56156
56157
56158         // Pick a representative tile near the center of the viewport
56159         // (This is useful for sampling the imagery vintage)
56160         var dims = geotile.size(),
56161             mapCenter = [dims[0] / 2, dims[1] / 2],
56162             minDist = Math.max(dims[0], dims[1]),
56163             nearCenter;
56164
56165         requests.forEach(function(d) {
56166             var c = tileCenter(d);
56167             var dist = geoEuclideanDistance(c, mapCenter);
56168             if (dist < minDist) {
56169                 minDist = dist;
56170                 nearCenter = d;
56171             }
56172         });
56173
56174
56175         var image = selection$$1.selectAll('img')
56176             .data(requests, function(d) { return d[3]; });
56177
56178         image.exit()
56179             .style(transformProp, imageTransform)
56180             .classed('tile-removing', true)
56181             .classed('tile-center', false)
56182             .each(function() {
56183                 var tile = select(this);
56184                 window.setTimeout(function() {
56185                     if (tile.classed('tile-removing')) {
56186                         tile.remove();
56187                     }
56188                 }, 300);
56189             });
56190
56191         image.enter()
56192           .append('img')
56193             .attr('class', 'tile')
56194             .attr('src', function(d) { return d[3]; })
56195             .on('error', error)
56196             .on('load', load)
56197           .merge(image)
56198             .style(transformProp, imageTransform)
56199             .classed('tile-debug', showDebug)
56200             .classed('tile-removing', false)
56201             .classed('tile-center', function(d) { return d === nearCenter; });
56202
56203
56204
56205         var debug = selection$$1.selectAll('.tile-label-debug')
56206             .data(showDebug ? requests : [], function(d) { return d[3]; });
56207
56208         debug.exit()
56209             .remove();
56210
56211         if (showDebug) {
56212             var debugEnter = debug.enter()
56213                 .append('div')
56214                 .attr('class', 'tile-label-debug');
56215
56216             debugEnter
56217                 .append('div')
56218                 .attr('class', 'tile-label-debug-coord');
56219
56220             debugEnter
56221                 .append('div')
56222                 .attr('class', 'tile-label-debug-vintage');
56223
56224             debug = debug.merge(debugEnter);
56225
56226             debug
56227                 .style(transformProp, debugTransform);
56228
56229             debug
56230                 .selectAll('.tile-label-debug-coord')
56231                 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
56232
56233             debug
56234                 .selectAll('.tile-label-debug-vintage')
56235                 .each(function(d) {
56236                     var span = select(this);
56237                     var center = context.projection.invert(tileCenter(d));
56238                     source.getVintage(center, d, function(err, result) {
56239                         span.text((result && result.range) ||
56240                             t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown')
56241                         );
56242                     });
56243                 });
56244         }
56245
56246     }
56247
56248
56249     background.projection = function(_) {
56250         if (!arguments.length) return projection$$1;
56251         projection$$1 = _;
56252         return background;
56253     };
56254
56255
56256     background.dimensions = function(_) {
56257         if (!arguments.length) return geotile.size();
56258         geotile.size(_);
56259         return background;
56260     };
56261
56262
56263     background.source = function(_) {
56264         if (!arguments.length) return source;
56265         source = _;
56266         cache = {};
56267         geotile.scaleExtent(source.scaleExtent);
56268         return background;
56269     };
56270
56271
56272     return background;
56273 }
56274
56275 function rendererBackground(context) {
56276     var dispatch$$1 = dispatch('change'),
56277         baseLayer = rendererTileLayer(context).projection(context.projection),
56278         overlayLayers = [],
56279         backgroundSources;
56280
56281
56282     function background(selection$$1) {
56283         var base = selection$$1.selectAll('.layer-background')
56284             .data([0]);
56285
56286         base.enter()
56287             .insert('div', '.layer-data')
56288             .attr('class', 'layer layer-background')
56289             .merge(base)
56290             .call(baseLayer);
56291
56292         var overlays = selection$$1.selectAll('.layer-overlay')
56293             .data(overlayLayers, function(d) { return d.source().name(); });
56294
56295         overlays.exit()
56296             .remove();
56297
56298         overlays.enter()
56299             .insert('div', '.layer-data')
56300             .attr('class', 'layer layer-overlay')
56301             .merge(overlays)
56302             .each(function(layer) { select(this).call(layer); });
56303     }
56304
56305
56306     background.updateImagery = function() {
56307         if (context.inIntro()) return;
56308
56309         var b = background.baseLayerSource(),
56310             o = overlayLayers
56311                 .filter(function (d) { return !d.source().isLocatorOverlay(); })
56312                 .map(function (d) { return d.source().id; })
56313                 .join(','),
56314             meters = geoOffsetToMeters(b.offset()),
56315             epsilon = 0.01,
56316             x = +meters[0].toFixed(2),
56317             y = +meters[1].toFixed(2),
56318             q = utilStringQs(window.location.hash.substring(1));
56319
56320         var id = b.id;
56321         if (id === 'custom') {
56322             id = 'custom:' + b.template();
56323         }
56324
56325         if (id) {
56326             q.background = id;
56327         } else {
56328             delete q.background;
56329         }
56330
56331         if (o) {
56332             q.overlays = o;
56333         } else {
56334             delete q.overlays;
56335         }
56336
56337         if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
56338             q.offset = x + ',' + y;
56339         } else {
56340             delete q.offset;
56341         }
56342
56343         if (!window.mocha) {
56344             window.location.replace('#' + utilQsString(q, true));
56345         }
56346
56347         var imageryUsed = [b.imageryUsed()];
56348
56349         overlayLayers
56350             .filter(function (d) { return !d.source().isLocatorOverlay(); })
56351             .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
56352
56353         var gpx = context.layers().layer('gpx');
56354         if (gpx && gpx.enabled() && gpx.hasGpx()) {
56355             imageryUsed.push('Local GPX');
56356         }
56357
56358         var mapillary_images = context.layers().layer('mapillary-images');
56359         if (mapillary_images && mapillary_images.enabled()) {
56360             imageryUsed.push('Mapillary Images');
56361         }
56362
56363         var mapillary_signs = context.layers().layer('mapillary-signs');
56364         if (mapillary_signs && mapillary_signs.enabled()) {
56365             imageryUsed.push('Mapillary Signs');
56366         }
56367
56368         context.history().imageryUsed(imageryUsed);
56369     };
56370
56371
56372     background.sources = function(extent$$1) {
56373         return backgroundSources.filter(function(source) {
56374             return source.intersects(extent$$1);
56375         });
56376     };
56377
56378
56379     background.dimensions = function(_) {
56380         if (!_) return;
56381         baseLayer.dimensions(_);
56382
56383         overlayLayers.forEach(function(layer) {
56384             layer.dimensions(_);
56385         });
56386     };
56387
56388
56389     background.baseLayerSource = function(d) {
56390         if (!arguments.length) return baseLayer.source();
56391
56392         // test source against OSM imagery blacklists..
56393         var osm = context.connection();
56394         if (!osm) return background;
56395
56396         var blacklists = context.connection().imageryBlacklists();
56397
56398         var template = d.template(),
56399             fail = false,
56400             tested = 0,
56401             regex, i;
56402
56403         for (i = 0; i < blacklists.length; i++) {
56404             try {
56405                 regex = new RegExp(blacklists[i]);
56406                 fail = regex.test(template);
56407                 tested++;
56408                 if (fail) break;
56409             } catch (e) {
56410                 /* noop */
56411             }
56412         }
56413
56414         // ensure at least one test was run.
56415         if (!tested) {
56416             regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
56417             fail = regex.test(template);
56418         }
56419
56420         baseLayer.source(!fail ? d : background.findSource('none'));
56421         dispatch$$1.call('change');
56422         background.updateImagery();
56423         return background;
56424     };
56425
56426
56427     background.findSource = function(id) {
56428         return lodash.find(backgroundSources, function(d) {
56429             return d.id && d.id === id;
56430         });
56431     };
56432
56433
56434     background.bing = function() {
56435         background.baseLayerSource(background.findSource('Bing'));
56436     };
56437
56438
56439     background.showsLayer = function(d) {
56440         return d.id === baseLayer.source().id ||
56441             overlayLayers.some(function(layer) { return d.id === layer.source().id; });
56442     };
56443
56444
56445     background.overlayLayerSources = function() {
56446         return overlayLayers.map(function (l) { return l.source(); });
56447     };
56448
56449
56450     background.toggleOverlayLayer = function(d) {
56451         var layer;
56452
56453         for (var i = 0; i < overlayLayers.length; i++) {
56454             layer = overlayLayers[i];
56455             if (layer.source() === d) {
56456                 overlayLayers.splice(i, 1);
56457                 dispatch$$1.call('change');
56458                 background.updateImagery();
56459                 return;
56460             }
56461         }
56462
56463         layer = rendererTileLayer(context)
56464             .source(d)
56465             .projection(context.projection)
56466             .dimensions(baseLayer.dimensions());
56467
56468         overlayLayers.push(layer);
56469         dispatch$$1.call('change');
56470         background.updateImagery();
56471     };
56472
56473
56474     background.nudge = function(d, zoom$$1) {
56475         baseLayer.source().nudge(d, zoom$$1);
56476         dispatch$$1.call('change');
56477         background.updateImagery();
56478         return background;
56479     };
56480
56481
56482     background.offset = function(d) {
56483         if (!arguments.length) return baseLayer.source().offset();
56484         baseLayer.source().offset(d);
56485         dispatch$$1.call('change');
56486         background.updateImagery();
56487         return background;
56488     };
56489
56490
56491     background.init = function() {
56492         function parseMap(qmap) {
56493             if (!qmap) return false;
56494             var args = qmap.split('/').map(Number);
56495             if (args.length < 3 || args.some(isNaN)) return false;
56496             return geoExtent$$1([args[2], args[1]]);
56497         }
56498
56499         var dataImagery = data.imagery || [],
56500             q = utilStringQs(window.location.hash.substring(1)),
56501             requested = q.background || q.layer,
56502             extent$$1 = parseMap(q.map),
56503             first,
56504             best;
56505
56506         // Add all the available imagery sources
56507         backgroundSources = dataImagery.map(function(source) {
56508             if (source.type === 'bing') {
56509                 return rendererBackgroundSource.Bing(source, dispatch$$1);
56510             } else {
56511                 return rendererBackgroundSource(source);
56512             }
56513         });
56514
56515         first = backgroundSources.length && backgroundSources[0];
56516
56517         // Add 'None'
56518         backgroundSources.unshift(rendererBackgroundSource.None());
56519
56520         // Add 'Custom'
56521         var template = context.storage('background-custom-template') || '';
56522         var custom = rendererBackgroundSource.Custom(template);
56523         backgroundSources.unshift(custom);
56524
56525
56526         // Decide which background layer to display
56527         if (!requested && extent$$1) {
56528             best = lodash.find(this.sources(extent$$1), function(s) { return s.best(); });
56529         }
56530         if (requested && requested.indexOf('custom:') === 0) {
56531             template = requested.replace(/^custom:/, '');
56532             background.baseLayerSource(custom.template(template));
56533             context.storage('background-custom-template', template);
56534         } else {
56535             background.baseLayerSource(
56536                 background.findSource(requested) ||
56537                 best ||
56538                 background.findSource('Bing') ||
56539                 first ||
56540                 background.findSource('none')
56541             );
56542         }
56543
56544         var locator = lodash.find(backgroundSources, function(d) {
56545             return d.overlay && d.default;
56546         });
56547
56548         if (locator) {
56549             background.toggleOverlayLayer(locator);
56550         }
56551
56552         var overlays = (q.overlays || '').split(',');
56553         overlays.forEach(function(overlay) {
56554             overlay = background.findSource(overlay);
56555             if (overlay) {
56556                 background.toggleOverlayLayer(overlay);
56557             }
56558         });
56559
56560         if (q.gpx) {
56561             var gpx = context.layers().layer('gpx');
56562             if (gpx) {
56563                 gpx.url(q.gpx);
56564             }
56565         }
56566
56567         if (q.offset) {
56568             var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
56569                 return !isNaN(n) && n;
56570             });
56571
56572             if (offset.length === 2) {
56573                 background.offset(geoMetersToOffset(offset));
56574             }
56575         }
56576     };
56577
56578
56579     return utilRebind(background, dispatch$$1, 'on');
56580 }
56581
56582 function rendererFeatures(context) {
56583     var traffic_roads = {
56584         'motorway': true,
56585         'motorway_link': true,
56586         'trunk': true,
56587         'trunk_link': true,
56588         'primary': true,
56589         'primary_link': true,
56590         'secondary': true,
56591         'secondary_link': true,
56592         'tertiary': true,
56593         'tertiary_link': true,
56594         'residential': true,
56595         'unclassified': true,
56596         'living_street': true
56597     };
56598
56599     var service_roads = {
56600         'service': true,
56601         'road': true,
56602         'track': true
56603     };
56604
56605     var paths = {
56606         'path': true,
56607         'footway': true,
56608         'cycleway': true,
56609         'bridleway': true,
56610         'steps': true,
56611         'pedestrian': true,
56612         'corridor': true
56613     };
56614
56615     var past_futures = {
56616         'proposed': true,
56617         'construction': true,
56618         'abandoned': true,
56619         'dismantled': true,
56620         'disused': true,
56621         'razed': true,
56622         'demolished': true,
56623         'obliterated': true
56624     };
56625
56626     var dispatch$$1 = dispatch('change', 'redraw'),
56627         _cullFactor = 1,
56628         _cache = {},
56629         _features = {},
56630         _stats = {},
56631         _keys = [],
56632         _hidden = [];
56633
56634
56635     function update() {
56636         _hidden = features.hidden();
56637         dispatch$$1.call('change');
56638         dispatch$$1.call('redraw');
56639     }
56640
56641
56642     function defineFeature(k, filter, max$$1) {
56643         _keys.push(k);
56644         _features[k] = {
56645             filter: filter,
56646             enabled: true,   // whether the user wants it enabled..
56647             count: 0,
56648             currentMax: (max$$1 || Infinity),
56649             defaultMax: (max$$1 || Infinity),
56650             enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
56651             disable: function() { this.enabled = false; this.currentMax = 0; },
56652             hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
56653             autoHidden: function() { return this.hidden() && this.currentMax > 0; }
56654         };
56655     }
56656
56657
56658     defineFeature('points', function isPoint(entity, resolver, geometry) {
56659         return geometry === 'point';
56660     }, 200);
56661
56662     defineFeature('traffic_roads', function isTrafficRoad(entity) {
56663         return traffic_roads[entity.tags.highway];
56664     });
56665
56666     defineFeature('service_roads', function isServiceRoad(entity) {
56667         return service_roads[entity.tags.highway];
56668     });
56669
56670     defineFeature('paths', function isPath(entity) {
56671         return paths[entity.tags.highway];
56672     });
56673
56674     defineFeature('buildings', function isBuilding(entity) {
56675         return (
56676             !!entity.tags['building:part'] ||
56677             (!!entity.tags.building && entity.tags.building !== 'no') ||
56678             entity.tags.amenity === 'shelter' ||
56679             entity.tags.parking === 'multi-storey' ||
56680             entity.tags.parking === 'sheds' ||
56681             entity.tags.parking === 'carports' ||
56682             entity.tags.parking === 'garage_boxes'
56683         );
56684     }, 250);
56685
56686     defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
56687         return geometry === 'area' &&
56688             !_features.buildings.filter(entity) &&
56689             !_features.water.filter(entity);
56690     });
56691
56692     defineFeature('boundaries', function isBoundary(entity) {
56693         return !!entity.tags.boundary;
56694     });
56695
56696     defineFeature('water', function isWater(entity) {
56697         return (
56698             !!entity.tags.waterway ||
56699             entity.tags.natural === 'water' ||
56700             entity.tags.natural === 'coastline' ||
56701             entity.tags.natural === 'bay' ||
56702             entity.tags.landuse === 'pond' ||
56703             entity.tags.landuse === 'basin' ||
56704             entity.tags.landuse === 'reservoir' ||
56705             entity.tags.landuse === 'salt_pond'
56706         );
56707     });
56708
56709     defineFeature('rail', function isRail(entity) {
56710         return (
56711             !!entity.tags.railway ||
56712             entity.tags.landuse === 'railway'
56713         ) && !(
56714             traffic_roads[entity.tags.highway] ||
56715             service_roads[entity.tags.highway] ||
56716             paths[entity.tags.highway]
56717         );
56718     });
56719
56720     defineFeature('power', function isPower(entity) {
56721         return !!entity.tags.power;
56722     });
56723
56724     // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
56725     defineFeature('past_future', function isPastFuture(entity) {
56726         if (
56727             traffic_roads[entity.tags.highway] ||
56728             service_roads[entity.tags.highway] ||
56729             paths[entity.tags.highway]
56730         ) { return false; }
56731
56732         var strings = Object.keys(entity.tags);
56733
56734         for (var i = 0; i < strings.length; i++) {
56735             var s = strings[i];
56736             if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
56737         }
56738         return false;
56739     });
56740
56741     // Lines or areas that don't match another feature filter.
56742     // IMPORTANT: The 'others' feature must be the last one defined,
56743     //   so that code in getMatches can skip this test if `hasMatch = true`
56744     defineFeature('others', function isOther(entity, resolver, geometry) {
56745         return (geometry === 'line' || geometry === 'area');
56746     });
56747
56748
56749     function features() {}
56750
56751
56752     features.features = function() {
56753         return _features;
56754     };
56755
56756
56757     features.keys = function() {
56758         return _keys;
56759     };
56760
56761
56762     features.enabled = function(k) {
56763         if (!arguments.length) {
56764             return _keys.filter(function(k) { return _features[k].enabled; });
56765         }
56766         return _features[k] && _features[k].enabled;
56767     };
56768
56769
56770     features.disabled = function(k) {
56771         if (!arguments.length) {
56772             return _keys.filter(function(k) { return !_features[k].enabled; });
56773         }
56774         return _features[k] && !_features[k].enabled;
56775     };
56776
56777
56778     features.hidden = function(k) {
56779         if (!arguments.length) {
56780             return _keys.filter(function(k) { return _features[k].hidden(); });
56781         }
56782         return _features[k] && _features[k].hidden();
56783     };
56784
56785
56786     features.autoHidden = function(k) {
56787         if (!arguments.length) {
56788             return _keys.filter(function(k) { return _features[k].autoHidden(); });
56789         }
56790         return _features[k] && _features[k].autoHidden();
56791     };
56792
56793
56794     features.enable = function(k) {
56795         if (_features[k] && !_features[k].enabled) {
56796             _features[k].enable();
56797             update();
56798         }
56799     };
56800
56801
56802     features.disable = function(k) {
56803         if (_features[k] && _features[k].enabled) {
56804             _features[k].disable();
56805             update();
56806         }
56807     };
56808
56809
56810     features.toggle = function(k) {
56811         if (_features[k]) {
56812             (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
56813             update();
56814         }
56815     };
56816
56817
56818     features.resetStats = function() {
56819         for (var i = 0; i < _keys.length; i++) {
56820             _features[_keys[i]].count = 0;
56821         }
56822         dispatch$$1.call('change');
56823     };
56824
56825
56826     features.gatherStats = function(d, resolver, dimensions) {
56827         var needsRedraw = false,
56828             type = lodash.groupBy(d, function(ent) { return ent.type; }),
56829             entities = [].concat(type.relation || [], type.way || [], type.node || []),
56830             currHidden, geometry, matches, i, j;
56831
56832         for (i = 0; i < _keys.length; i++) {
56833             _features[_keys[i]].count = 0;
56834         }
56835
56836         // adjust the threshold for point/building culling based on viewport size..
56837         // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
56838         _cullFactor = dimensions[0] * dimensions[1] / 1000000;
56839
56840         for (i = 0; i < entities.length; i++) {
56841             geometry = entities[i].geometry(resolver);
56842             if (!(geometry === 'vertex' || geometry === 'relation')) {
56843                 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
56844                 for (j = 0; j < matches.length; j++) {
56845                     _features[matches[j]].count++;
56846                 }
56847             }
56848         }
56849
56850         currHidden = features.hidden();
56851         if (currHidden !== _hidden) {
56852             _hidden = currHidden;
56853             needsRedraw = true;
56854             dispatch$$1.call('change');
56855         }
56856
56857         return needsRedraw;
56858     };
56859
56860
56861     features.stats = function() {
56862         for (var i = 0; i < _keys.length; i++) {
56863             _stats[_keys[i]] = _features[_keys[i]].count;
56864         }
56865
56866         return _stats;
56867     };
56868
56869
56870     features.clear = function(d) {
56871         for (var i = 0; i < d.length; i++) {
56872             features.clearEntity(d[i]);
56873         }
56874     };
56875
56876
56877     features.clearEntity = function(entity) {
56878         delete _cache[osmEntity$$1.key(entity)];
56879     };
56880
56881
56882     features.reset = function() {
56883         _cache = {};
56884     };
56885
56886
56887     features.getMatches = function(entity, resolver, geometry) {
56888         if (geometry === 'vertex' || geometry === 'relation') return {};
56889
56890         var ent = osmEntity$$1.key(entity);
56891         if (!_cache[ent]) {
56892             _cache[ent] = {};
56893         }
56894
56895         if (!_cache[ent].matches) {
56896             var matches = {},
56897                 hasMatch = false;
56898
56899             for (var i = 0; i < _keys.length; i++) {
56900                 if (_keys[i] === 'others') {
56901                     if (hasMatch) continue;
56902
56903                     // Multipolygon members:
56904                     // If an entity...
56905                     //   1. is a way that hasn't matched other 'interesting' feature rules,
56906                     //   2. and it belongs to a single parent multipolygon relation
56907                     // ...then match whatever feature rules the parent multipolygon has matched.
56908                     // see #2548, #2887
56909                     //
56910                     // IMPORTANT:
56911                     // For this to work, getMatches must be called on relations before ways.
56912                     //
56913                     if (entity.type === 'way') {
56914                         var parents = features.getParents(entity, resolver, geometry);
56915                         if (parents.length === 1 && parents[0].isMultipolygon()) {
56916                             var pkey = osmEntity$$1.key(parents[0]);
56917                             if (_cache[pkey] && _cache[pkey].matches) {
56918                                 matches = lodash.clone(_cache[pkey].matches);
56919                                 continue;
56920                             }
56921                         }
56922                     }
56923                 }
56924
56925                 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
56926                     matches[_keys[i]] = hasMatch = true;
56927                 }
56928             }
56929             _cache[ent].matches = matches;
56930         }
56931
56932         return _cache[ent].matches;
56933     };
56934
56935
56936     features.getParents = function(entity, resolver, geometry) {
56937         if (geometry === 'point') return [];
56938
56939         var ent = osmEntity$$1.key(entity);
56940         if (!_cache[ent]) {
56941             _cache[ent] = {};
56942         }
56943
56944         if (!_cache[ent].parents) {
56945             var parents = [];
56946             if (geometry === 'vertex') {
56947                 parents = resolver.parentWays(entity);
56948             } else {   // 'line', 'area', 'relation'
56949                 parents = resolver.parentRelations(entity);
56950             }
56951             _cache[ent].parents = parents;
56952         }
56953         return _cache[ent].parents;
56954     };
56955
56956
56957     features.isHiddenFeature = function(entity, resolver, geometry) {
56958         if (!_hidden.length) return false;
56959         if (!entity.version) return false;
56960
56961         var matches = features.getMatches(entity, resolver, geometry);
56962
56963         for (var i = 0; i < _hidden.length; i++) {
56964             if (matches[_hidden[i]]) return true;
56965         }
56966         return false;
56967     };
56968
56969
56970     features.isHiddenChild = function(entity, resolver, geometry) {
56971         if (!_hidden.length) return false;
56972         if (!entity.version || geometry === 'point') return false;
56973
56974         var parents = features.getParents(entity, resolver, geometry);
56975         if (!parents.length) return false;
56976
56977         for (var i = 0; i < parents.length; i++) {
56978             if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
56979                 return false;
56980             }
56981         }
56982         return true;
56983     };
56984
56985
56986     features.hasHiddenConnections = function(entity, resolver) {
56987         if (!_hidden.length) return false;
56988         var childNodes, connections;
56989
56990         if (entity.type === 'midpoint') {
56991             childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
56992             connections = [];
56993         } else {
56994             childNodes = entity.nodes ? resolver.childNodes(entity) : [];
56995             connections = features.getParents(entity, resolver, entity.geometry(resolver));
56996         }
56997
56998         // gather ways connected to child nodes..
56999         connections = lodash.reduce(childNodes, function(result, e) {
57000             return resolver.isShared(e) ? lodash.union(result, resolver.parentWays(e)) : result;
57001         }, connections);
57002
57003         return connections.length ? lodash.some(connections, function(e) {
57004             return features.isHidden(e, resolver, e.geometry(resolver));
57005         }) : false;
57006     };
57007
57008
57009     features.isHidden = function(entity, resolver, geometry) {
57010         if (!_hidden.length) return false;
57011         if (!entity.version) return false;
57012
57013         var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
57014         return fn(entity, resolver, geometry);
57015     };
57016
57017
57018     features.filter = function(d, resolver) {
57019         if (!_hidden.length) return d;
57020
57021         var result = [];
57022         for (var i = 0; i < d.length; i++) {
57023             var entity = d[i];
57024             if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
57025                 result.push(entity);
57026             }
57027         }
57028         return result;
57029     };
57030
57031
57032     return utilRebind(features, dispatch$$1, 'on');
57033 }
57034
57035 function utilBindOnce(target, type, listener, capture) {
57036     var typeOnce = type + '.once';
57037     function one() {
57038         target.on(typeOnce, null);
57039         listener.apply(this, arguments);
57040     }
57041     target.on(typeOnce, one, capture);
57042     return this;
57043 }
57044
57045 function rendererMap(context) {
57046
57047     var dimensions = [1, 1],
57048         dispatch$$1 = dispatch('move', 'drawn'),
57049         projection$$1 = context.projection,
57050         curtainProjection = context.curtainProjection,
57051         dblclickEnabled = true,
57052         redrawEnabled = true,
57053         transformStart = projection$$1.transform(),
57054         transformLast,
57055         transformed = false,
57056         minzoom = 0,
57057         drawLayers = svgLayers(projection$$1, context),
57058         drawPoints = svgPoints$$1(projection$$1, context),
57059         drawVertices = svgVertices$$1(projection$$1, context),
57060         drawLines = svgLines$$1(projection$$1, context),
57061         drawAreas = svgAreas$$1(projection$$1, context),
57062         drawMidpoints = svgMidpoints$$1(projection$$1, context),
57063         drawLabels = svgLabels(projection$$1, context),
57064         supersurface = select(null),
57065         wrapper = select(null),
57066         surface = select(null),
57067         mouse$$1,
57068         mousemove;
57069
57070     var zoom$$1 = zoom()
57071             .scaleExtent([ztok(2), ztok(24)])
57072             .interpolate(interpolateValue)
57073             .filter(zoomEventFilter)
57074             .on('zoom', zoomPan);
57075
57076     var _selection = select(null);
57077     var isRedrawScheduled = false;
57078     var pendingRedrawCall;
57079
57080     function scheduleRedraw() {
57081         // Only schedule the redraw if one has not already been set.
57082         if (isRedrawScheduled) return;
57083         isRedrawScheduled = true;
57084         var that = this;
57085         var args = arguments;
57086         pendingRedrawCall = requestIdleCallback(function () {
57087             // Reset the boolean so future redraws can be set.
57088             isRedrawScheduled = false;
57089             redraw.apply(that, args);
57090         }, { timeout: 1400 });
57091     }
57092
57093     function cancelPendingRedraw() {
57094         isRedrawScheduled = false;
57095         window.cancelIdleCallback(pendingRedrawCall);
57096     }
57097         
57098     function map(selection$$1) {
57099
57100         _selection = selection$$1;
57101
57102         context
57103             .on('change.map', immediateRedraw);
57104
57105         var osm = context.connection();
57106         if (osm) {
57107             osm.on('change.map', immediateRedraw);
57108         }
57109
57110         context.history()
57111             .on('change.map', immediateRedraw)
57112             .on('undone.map redone.map', function(stack$$1) {
57113                 var mode = context.mode().id;
57114                 if (mode !== 'browse' && mode !== 'select') return;
57115
57116                 var followSelected = false;
57117                 if (Array.isArray(stack$$1.selectedIDs)) {
57118                     followSelected = (stack$$1.selectedIDs.length === 1 && stack$$1.selectedIDs[0][0] === 'n');
57119                     context.enter(
57120                         modeSelect(context, stack$$1.selectedIDs).follow(followSelected)
57121                     );
57122                 }
57123                 if (!followSelected && stack$$1.transform) {
57124                     map.transformEase(stack$$1.transform);
57125                 }
57126             });
57127
57128         context.background()
57129             .on('change.map', immediateRedraw);
57130
57131         context.features()
57132             .on('redraw.map', immediateRedraw);
57133
57134         drawLayers
57135             .on('change.map', function() {
57136                 context.background().updateImagery();
57137                 immediateRedraw();
57138             });
57139
57140         selection$$1
57141             .on('dblclick.map', dblClick)
57142             .call(zoom$$1)
57143             .call(zoom$$1.transform, projection$$1.transform());
57144
57145         supersurface = selection$$1.append('div')
57146             .attr('id', 'supersurface')
57147             .call(utilSetTransform, 0, 0);
57148
57149         // Need a wrapper div because Opera can't cope with an absolutely positioned
57150         // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
57151         wrapper = supersurface
57152             .append('div')
57153             .attr('class', 'layer layer-data');
57154
57155         map.surface = surface = wrapper
57156             .call(drawLayers)
57157             .selectAll('.surface')
57158             .attr('id', 'surface');
57159
57160         surface
57161             .call(drawLabels.observe)
57162             .on('mousedown.zoom', function() {
57163                 if (event.button === 2) {
57164                     event.stopPropagation();
57165                 }
57166             }, true)
57167             .on('mouseup.zoom', function() {
57168                 if (resetTransform()) immediateRedraw();
57169             })
57170             .on('mousemove.map', function() {
57171                 mousemove = event;
57172             })
57173             .on('mouseover.vertices', function() {
57174                 if (map.editable() && !transformed) {
57175                     var hover = event.target.__data__;
57176                     surface.selectAll('.data-layer-osm')
57177                         .call(drawVertices.drawHover, context.graph(), hover, map.extent(), map.zoom());
57178                     dispatch$$1.call('drawn', this, {full: false});
57179                 }
57180             })
57181             .on('mouseout.vertices', function() {
57182                 if (map.editable() && !transformed) {
57183                     var hover = event.relatedTarget && event.relatedTarget.__data__;
57184                     surface.selectAll('.data-layer-osm')
57185                         .call(drawVertices.drawHover, context.graph(), hover, map.extent(), map.zoom());
57186                     dispatch$$1.call('drawn', this, {full: false});
57187                 }
57188             });
57189
57190         supersurface
57191             .call(context.background());
57192
57193         context.on('enter.map', function() {
57194             if (map.editable() && !transformed) {
57195                 var all = context.intersects(map.extent()),
57196                     filter = utilFunctor(true),
57197                     graph = context.graph();
57198
57199                 all = context.features().filter(all, graph);
57200                 surface.selectAll('.data-layer-osm')
57201                     .call(drawVertices, graph, all, filter, map.extent(), map.zoom())
57202                     .call(drawMidpoints, graph, all, filter, map.trimmedExtent());
57203                 dispatch$$1.call('drawn', this, {full: false});
57204             }
57205         });
57206
57207         map.dimensions(utilGetDimensions(selection$$1));
57208     }
57209
57210
57211     function zoomEventFilter() {
57212         // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
57213         // Intercept `mousedown` and check if there is an orphaned zoom gesture.
57214         // This can happen if a previous `mousedown` occurred without a `mouseup`.
57215         // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
57216         // so that d3-zoom won't stop propagation of new `mousedown` events.
57217         if (event.type === 'mousedown') {
57218             var hasOrphan = false;
57219             var listeners = window.__on;
57220             for (var i = 0; i < listeners.length; i++) {
57221                 var listener = listeners[i];
57222                 if (listener.name === 'zoom' && listener.type === 'mouseup') {
57223                     hasOrphan = true;
57224                     break;
57225                 }
57226             }
57227             if (hasOrphan) {
57228                 var event$$1 = window.CustomEvent;
57229                 if (event$$1) {
57230                     event$$1 = new event$$1('mouseup');
57231                 } else {
57232                     event$$1 = window.document.createEvent('Event');
57233                     event$$1.initEvent('mouseup', false, false);
57234                 }
57235                 // Event needs to be dispatched with an event.view property.
57236                 event$$1.view = window;
57237                 window.dispatchEvent(event$$1);
57238             }
57239         }
57240
57241         return event.button !== 2;   // ignore right clicks
57242     }
57243
57244
57245     function ztok(z) {
57246         return 256 * Math.pow(2, z);
57247     }
57248
57249     function ktoz(k) {
57250         return Math.max(Math.log(k) / Math.LN2 - 8, 0);
57251     }
57252
57253     function pxCenter() {
57254         return [dimensions[0] / 2, dimensions[1] / 2];
57255     }
57256
57257
57258     function drawVector(difference, extent$$1) {
57259         var graph = context.graph(),
57260             features = context.features(),
57261             all = context.intersects(map.extent()),
57262             data, filter;
57263
57264         if (difference) {
57265             var complete = difference.complete(map.extent());
57266             data = lodash.compact(lodash.values(complete));
57267             filter = function(d) { return d.id in complete; };
57268             features.clear(data);
57269
57270         } else {
57271             // force a full redraw if gatherStats detects that a feature
57272             // should be auto-hidden (e.g. points or buildings)..
57273             if (features.gatherStats(all, graph, dimensions)) {
57274                 extent$$1 = undefined;
57275             }
57276
57277             if (extent$$1) {
57278                 data = context.intersects(map.extent().intersection(extent$$1));
57279                 var set = set$2(lodash.map(data, 'id'));
57280                 filter = function(d) { return set.has(d.id); };
57281
57282             } else {
57283                 data = all;
57284                 filter = utilFunctor(true);
57285             }
57286         }
57287
57288         data = features.filter(data, graph);
57289
57290         surface.selectAll('.data-layer-osm')
57291             .call(drawVertices, graph, data, filter, map.extent(), map.zoom())
57292             .call(drawLines, graph, data, filter)
57293             .call(drawAreas, graph, data, filter)
57294             .call(drawMidpoints, graph, data, filter, map.trimmedExtent())
57295             .call(drawLabels, graph, data, filter, dimensions, !difference && !extent$$1)
57296             .call(drawPoints, graph, data, filter);
57297
57298         dispatch$$1.call('drawn', this, {full: true});
57299     }
57300
57301
57302     function editOff() {
57303         context.features().resetStats();
57304         surface.selectAll('.layer-osm *').remove();
57305         context.enter(modeBrowse(context));
57306         dispatch$$1.call('drawn', this, {full: true});
57307     }
57308
57309
57310     function dblClick() {
57311         if (!dblclickEnabled) {
57312             event.preventDefault();
57313             event.stopImmediatePropagation();
57314         }
57315     }
57316
57317
57318     function zoomPan(manualEvent) {
57319         var event$$1 = (manualEvent || event),
57320             source = event$$1.sourceEvent,
57321             eventTransform = event$$1.transform;
57322
57323         if (transformStart.x === eventTransform.x &&
57324             transformStart.y === eventTransform.y &&
57325             transformStart.k === eventTransform.k) {
57326             return;  // no change
57327         }
57328
57329         // Normalize mousewheel - #3029
57330         // If wheel delta is provided in LINE units, recalculate it in PIXEL units
57331         // We are essentially redoing the calculations that occur here:
57332         //   https://github.com/d3/d3-zoom/blob/78563a8348aa4133b07cac92e2595c2227ca7cd7/src/zoom.js#L203
57333         // See this for more info:
57334         //   https://github.com/basilfx/normalize-wheel/blob/master/src/normalizeWheel.js
57335         if (source && source.type === 'wheel' && source.deltaMode === 1 /* LINE */) {
57336             // pick sensible scroll amount if user scrolling fast or slow..
57337             var lines = Math.abs(source.deltaY),
57338                 scroll = lines > 2 ? 40 : lines * 10;
57339
57340             var t0 = transformed ? transformLast : transformStart,
57341                 p0 = mouse$$1(source),
57342                 p1 = t0.invert(p0),
57343                 k2 = t0.k * Math.pow(2, -source.deltaY * scroll / 500),
57344                 x2 = p0[0] - p1[0] * k2,
57345                 y2 = p0[1] - p1[1] * k2;
57346
57347             eventTransform = identity$8.translate(x2,y2).scale(k2);
57348             _selection.node().__zoom = eventTransform;
57349         }
57350
57351         if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
57352             surface.interrupt();
57353             uiFlash().text(t('cannot_zoom'));
57354             setZoom(context.minEditableZoom(), true);
57355             scheduleRedraw();
57356             dispatch$$1.call('move', this, map);
57357             return;
57358         }
57359
57360         projection$$1.transform(eventTransform);
57361
57362         var scale = eventTransform.k / transformStart.k,
57363             tX = (eventTransform.x / scale - transformStart.x) * scale,
57364             tY = (eventTransform.y / scale - transformStart.y) * scale;
57365
57366         if (context.inIntro()) {
57367             curtainProjection.transform({
57368                 x: eventTransform.x - tX,
57369                 y: eventTransform.y - tY,
57370                 k: eventTransform.k
57371             });
57372         }
57373
57374         mousemove = event$$1;
57375         transformed = true;
57376         transformLast = eventTransform;
57377         utilSetTransform(supersurface, tX, tY, scale);
57378         scheduleRedraw();
57379
57380         dispatch$$1.call('move', this, map);
57381     }
57382
57383
57384     function resetTransform() {
57385         if (!transformed) return false;
57386
57387         // deprecation warning - Radial Menu to be removed in iD v3
57388         surface.selectAll('.edit-menu, .radial-menu').interrupt().remove();
57389         utilSetTransform(supersurface, 0, 0);
57390         transformed = false;
57391         if (context.inIntro()) {
57392             curtainProjection.transform(projection$$1.transform());
57393         }
57394         return true;
57395     }
57396
57397
57398     function redraw(difference, extent$$1) {
57399         if (surface.empty() || !redrawEnabled) return;
57400
57401         // If we are in the middle of a zoom/pan, we can't do differenced redraws.
57402         // It would result in artifacts where differenced entities are redrawn with
57403         // one transform and unchanged entities with another.
57404         if (resetTransform()) {
57405             difference = extent$$1 = undefined;
57406         }
57407
57408         var z = String(~~map.zoom());
57409         if (surface.attr('data-zoom') !== z) {
57410             surface.attr('data-zoom', z)
57411                 .classed('low-zoom', z <= 16);
57412         }
57413
57414         if (!difference) {
57415             supersurface.call(context.background());
57416         }
57417
57418         wrapper
57419             .call(drawLayers);
57420
57421         // OSM
57422         if (map.editable()) {
57423             context.loadTiles(projection$$1, dimensions);
57424             drawVector(difference, extent$$1);
57425         } else {
57426             editOff();
57427         }
57428
57429         transformStart = projection$$1.transform();
57430
57431         return map;
57432     }
57433
57434
57435
57436     var immediateRedraw = function(difference, extent$$1) {
57437         if (!difference && !extent$$1) cancelPendingRedraw();
57438         redraw(difference, extent$$1);
57439     };
57440
57441
57442     function pointLocation(p) {
57443         var translate = projection$$1.translate(),
57444             scale = projection$$1.scale() * 2 * Math.PI;
57445         return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
57446     }
57447
57448
57449     function locationPoint(l) {
57450         var translate = projection$$1.translate(),
57451             scale = projection$$1.scale() * 2 * Math.PI;
57452         return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
57453     }
57454
57455
57456     map.mouse = function() {
57457         var event$$1 = mousemove || event;
57458         if (event$$1) {
57459             var s;
57460             while ((s = event$$1.sourceEvent)) { event$$1 = s; }
57461             return mouse$$1(event$$1);
57462         }
57463         return null;
57464     };
57465
57466
57467     map.mouseCoordinates = function() {
57468         return projection$$1.invert(map.mouse());
57469     };
57470
57471
57472     map.dblclickEnable = function(_) {
57473         if (!arguments.length) return dblclickEnabled;
57474         dblclickEnabled = _;
57475         return map;
57476     };
57477
57478
57479     map.redrawEnable = function(_) {
57480         if (!arguments.length) return redrawEnabled;
57481         redrawEnabled = _;
57482         return map;
57483     };
57484
57485
57486     function setTransform(t2, duration, force) {
57487         var t$$1 = projection$$1.transform();
57488         if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
57489             return false;
57490         }
57491
57492         if (duration) {
57493             _selection
57494                 .transition()
57495                 .duration(duration)
57496                 .on('start', function() { map.startEase(); })
57497                 .call(zoom$$1.transform, identity$8.translate(t2.x, t2.y).scale(t2.k));
57498         } else {
57499             projection$$1.transform(t2);
57500             transformStart = t2;
57501             _selection.call(zoom$$1.transform, transformStart);
57502         }
57503     }
57504
57505
57506     function setZoom(z2, force, duration) {
57507         if (z2 === map.zoom() && !force) {
57508             return false;
57509         }
57510
57511         var k = projection$$1.scale(),
57512             k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
57513             center = pxCenter(),
57514             l = pointLocation(center);
57515
57516         projection$$1.scale(k2);
57517
57518         var t$$1 = projection$$1.translate();
57519         l = locationPoint(l);
57520
57521         t$$1[0] += center[0] - l[0];
57522         t$$1[1] += center[1] - l[1];
57523
57524         if (duration) {
57525             projection$$1.scale(k);  // reset scale
57526             _selection
57527                 .transition()
57528                 .duration(duration)
57529                 .on('start', function() { map.startEase(); })
57530                 .call(zoom$$1.transform, identity$8.translate(t$$1[0], t$$1[1]).scale(k2));
57531         } else {
57532             projection$$1.translate(t$$1);
57533             transformStart = projection$$1.transform();
57534             _selection.call(zoom$$1.transform, transformStart);
57535         }
57536
57537         return true;
57538     }
57539
57540
57541     function setCenter(loc2, duration) {
57542         var c = map.center();
57543         if (loc2[0] === c[0] && loc2[1] === c[1]) {
57544             return false;
57545         }
57546
57547         var t$$1 = projection$$1.translate(),
57548             k = projection$$1.scale(),
57549             pxC = pxCenter(),
57550             ll = projection$$1(loc2);
57551
57552         t$$1[0] = t$$1[0] - ll[0] + pxC[0];
57553         t$$1[1] = t$$1[1] - ll[1] + pxC[1];
57554
57555         if (duration) {
57556             _selection
57557                 .transition()
57558                 .duration(duration)
57559                 .on('start', function() { map.startEase(); })
57560                 .call(zoom$$1.transform, identity$8.translate(t$$1[0], t$$1[1]).scale(k));
57561         } else {
57562             projection$$1.translate(t$$1);
57563             transformStart = projection$$1.transform();
57564             _selection.call(zoom$$1.transform, transformStart);
57565         }
57566
57567         return true;
57568     }
57569
57570
57571     map.pan = function(delta, duration) {
57572         var t$$1 = projection$$1.translate(),
57573             k = projection$$1.scale();
57574
57575         t$$1[0] += delta[0];
57576         t$$1[1] += delta[1];
57577
57578         if (duration) {
57579             _selection
57580                 .transition()
57581                 .duration(duration)
57582                 .on('start', function() { map.startEase(); })
57583                 .call(zoom$$1.transform, identity$8.translate(t$$1[0], t$$1[1]).scale(k));
57584         } else {
57585             projection$$1.translate(t$$1);
57586             transformStart = projection$$1.transform();
57587             _selection.call(zoom$$1.transform, transformStart);
57588             dispatch$$1.call('move', this, map);
57589             immediateRedraw();
57590         }
57591
57592         return map;
57593     };
57594
57595
57596     map.dimensions = function(_) {
57597         if (!arguments.length) return dimensions;
57598         var center = map.center();
57599         dimensions = _;
57600         drawLayers.dimensions(dimensions);
57601         context.background().dimensions(dimensions);
57602         projection$$1.clipExtent([[0, 0], dimensions]);
57603         mouse$$1 = utilFastMouse(supersurface.node());
57604         setCenter(center);
57605
57606         scheduleRedraw();
57607         return map;
57608     };
57609
57610
57611     function zoomIn(delta) {
57612         setZoom(~~map.zoom() + delta, true, 250);
57613     }
57614
57615     function zoomOut(delta) {
57616         setZoom(~~map.zoom() - delta, true, 250);
57617     }
57618
57619     map.zoomIn = function() { zoomIn(1); };
57620     map.zoomInFurther = function() { zoomIn(4); };
57621
57622     map.zoomOut = function() { zoomOut(1); };
57623     map.zoomOutFurther = function() { zoomOut(4); };
57624
57625
57626     map.center = function(loc2) {
57627         if (!arguments.length) {
57628             return projection$$1.invert(pxCenter());
57629         }
57630
57631         if (setCenter(loc2)) {
57632             dispatch$$1.call('move', this, map);
57633         }
57634
57635         scheduleRedraw();
57636         return map;
57637     };
57638
57639
57640     map.zoom = function(z2) {
57641         if (!arguments.length) {
57642             return Math.max(ktoz(projection$$1.scale() * 2 * Math.PI), 0);
57643         }
57644
57645         if (z2 < minzoom) {
57646             surface.interrupt();
57647             uiFlash().text(t('cannot_zoom'));
57648             z2 = context.minEditableZoom();
57649         }
57650
57651         if (setZoom(z2)) {
57652             dispatch$$1.call('move', this, map);
57653         }
57654
57655         scheduleRedraw();
57656         return map;
57657     };
57658
57659
57660     map.zoomTo = function(entity, zoomLimits) {
57661         var extent$$1 = entity.extent(context.graph());
57662         if (!isFinite(extent$$1.area())) return;
57663
57664         var z2 = map.trimmedExtentZoom(extent$$1);
57665         zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
57666         map.centerZoom(extent$$1.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
57667     };
57668
57669
57670     map.centerZoom = function(loc2, z2) {
57671         var centered = setCenter(loc2),
57672             zoomed   = setZoom(z2);
57673
57674         if (centered || zoomed) {
57675             dispatch$$1.call('move', this, map);
57676         }
57677
57678         scheduleRedraw();
57679         return map;
57680     };
57681
57682
57683     map.centerEase = function(loc2, duration) {
57684         duration = duration || 250;
57685         setCenter(loc2, duration);
57686         return map;
57687     };
57688
57689
57690     map.zoomEase = function(z2, duration) {
57691         duration = duration || 250;
57692         setZoom(z2, false, duration);
57693         return map;
57694     };
57695
57696
57697     map.transformEase = function(t2, duration) {
57698         duration = duration || 250;
57699         setTransform(t2, duration, false);
57700         return map;
57701     };
57702
57703
57704     map.startEase = function() {
57705         utilBindOnce(surface, 'mousedown.ease', function() {
57706             map.cancelEase();
57707         });
57708         return map;
57709     };
57710
57711
57712     map.cancelEase = function() {
57713         _selection.interrupt();
57714         return map;
57715     };
57716
57717
57718     map.extent = function(_) {
57719         if (!arguments.length) {
57720             return new geoExtent$$1(projection$$1.invert([0, dimensions[1]]),
57721                                  projection$$1.invert([dimensions[0], 0]));
57722         } else {
57723             var extent$$1 = geoExtent$$1(_);
57724             map.centerZoom(extent$$1.center(), map.extentZoom(extent$$1));
57725         }
57726     };
57727
57728
57729     map.trimmedExtent = function(_) {
57730         if (!arguments.length) {
57731             var headerY = 60, footerY = 30, pad = 10;
57732             return new geoExtent$$1(projection$$1.invert([pad, dimensions[1] - footerY - pad]),
57733                                  projection$$1.invert([dimensions[0] - pad, headerY + pad]));
57734         } else {
57735             var extent$$1 = geoExtent$$1(_);
57736             map.centerZoom(extent$$1.center(), map.trimmedExtentZoom(extent$$1));
57737         }
57738     };
57739
57740
57741     function calcZoom(extent$$1, dim) {
57742         var tl = projection$$1([extent$$1[0][0], extent$$1[1][1]]),
57743             br = projection$$1([extent$$1[1][0], extent$$1[0][1]]);
57744
57745         // Calculate maximum zoom that fits extent
57746         var hFactor = (br[0] - tl[0]) / dim[0],
57747             vFactor = (br[1] - tl[1]) / dim[1],
57748             hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
57749             vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
57750             newZoom = map.zoom() - Math.max(hZoomDiff, vZoomDiff);
57751
57752         return newZoom;
57753     }
57754
57755
57756     map.extentZoom = function(_) {
57757         return calcZoom(geoExtent$$1(_), dimensions);
57758     };
57759
57760
57761     map.trimmedExtentZoom = function(_) {
57762         var trimY = 120, trimX = 40,
57763             trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
57764         return calcZoom(geoExtent$$1(_), trimmed);
57765     };
57766
57767
57768     map.editable = function() {
57769         return map.zoom() >= context.minEditableZoom();
57770     };
57771
57772
57773     map.minzoom = function(_) {
57774         if (!arguments.length) return minzoom;
57775         minzoom = _;
57776         return map;
57777     };
57778
57779
57780     map.layers = drawLayers;
57781
57782
57783     return utilRebind(map, dispatch$$1, 'on');
57784 }
57785
57786 var TAU = 2 * Math.PI;
57787 function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
57788 function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
57789 function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
57790 function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
57791
57792
57793 function uiMapInMap(context) {
57794
57795
57796     function map_in_map(selection$$1) {
57797         var backgroundLayer = rendererTileLayer(context),
57798             overlayLayers = {},
57799             projection$$1 = geoRawMercator(),
57800             gpxLayer = svgGpx(projection$$1, context).showLabels(false),
57801             debugLayer = svgDebug(projection$$1, context),
57802             zoom$$1 = zoom()
57803                 .scaleExtent([ztok(0.5), ztok(24)])
57804                 .on('start', zoomStarted)
57805                 .on('zoom', zoomed)
57806                 .on('end', zoomEnded),
57807             isTransformed = false,
57808             isHidden = true,
57809             skipEvents = false,
57810             gesture = null,
57811             zDiff = 6,    // by default, minimap renders at (main zoom - 6)
57812             wrap = select(null),
57813             tiles = select(null),
57814             viewport = select(null),
57815             tStart,  // transform at start of gesture
57816             tCurr,   // transform at most recent event
57817             timeoutId;
57818
57819
57820         function zoomStarted() {
57821             if (skipEvents) return;
57822             tStart = tCurr = projection$$1.transform();
57823             gesture = null;
57824         }
57825
57826
57827         function zoomed() {
57828             if (skipEvents) return;
57829
57830             var x = event.transform.x,
57831                 y = event.transform.y,
57832                 k = event.transform.k,
57833                 isZooming = (k !== tStart.k),
57834                 isPanning = (x !== tStart.x || y !== tStart.y);
57835
57836             if (!isZooming && !isPanning) {
57837                 return;  // no change
57838             }
57839
57840             // lock in either zooming or panning, don't allow both in minimap.
57841             if (!gesture) {
57842                 gesture = isZooming ? 'zoom' : 'pan';
57843             }
57844
57845             var tMini = projection$$1.transform(),
57846                 tX, tY, scale;
57847
57848             if (gesture === 'zoom') {
57849                 var dMini = utilGetDimensions(wrap),
57850                     cMini = vecScale(dMini, 0.5);
57851                 scale = k / tMini.k;
57852                 tX = (cMini[0] / scale - cMini[0]) * scale;
57853                 tY = (cMini[1] / scale - cMini[1]) * scale;
57854             } else {
57855                 k = tMini.k;
57856                 scale = 1;
57857                 tX = x - tMini.x;
57858                 tY = y - tMini.y;
57859             }
57860
57861             utilSetTransform(tiles, tX, tY, scale);
57862             utilSetTransform(viewport, 0, 0, scale);
57863             isTransformed = true;
57864             tCurr = identity$8.translate(x, y).scale(k);
57865
57866             var zMain = ktoz(context.projection.scale()),
57867                 zMini = ktoz(k);
57868
57869             zDiff = zMain - zMini;
57870
57871             queueRedraw();
57872         }
57873
57874
57875         function zoomEnded() {
57876             if (skipEvents) return;
57877             if (gesture !== 'pan') return;
57878
57879             updateProjection();
57880             gesture = null;
57881             var dMini = utilGetDimensions(wrap),
57882                 cMini = vecScale(dMini, 0.5);
57883             context.map().center(projection$$1.invert(cMini));   // recenter main map..
57884         }
57885
57886
57887         function updateProjection() {
57888             var loc = context.map().center(),
57889                 dMini = utilGetDimensions(wrap),
57890                 cMini = vecScale(dMini, 0.5),
57891                 tMain = context.projection.transform(),
57892                 zMain = ktoz(tMain.k),
57893                 zMini = Math.max(zMain - zDiff, 0.5),
57894                 kMini = ztok(zMini);
57895
57896             projection$$1
57897                 .translate([tMain.x, tMain.y])
57898                 .scale(kMini);
57899
57900             var point = projection$$1(loc),
57901                 mouse$$1 = (gesture === 'pan') ? vecSub([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0],
57902                 xMini = cMini[0] - point[0] + tMain.x + mouse$$1[0],
57903                 yMini = cMini[1] - point[1] + tMain.y + mouse$$1[1];
57904
57905             projection$$1
57906                 .translate([xMini, yMini])
57907                 .clipExtent([[0, 0], dMini]);
57908
57909             tCurr = projection$$1.transform();
57910
57911             if (isTransformed) {
57912                 utilSetTransform(tiles, 0, 0);
57913                 utilSetTransform(viewport, 0, 0);
57914                 isTransformed = false;
57915             }
57916
57917             zoom$$1
57918                 .scaleExtent([ztok(0.5), ztok(zMain - 3)]);
57919
57920             skipEvents = true;
57921             wrap.call(zoom$$1.transform, tCurr);
57922             skipEvents = false;
57923         }
57924
57925
57926         function redraw() {
57927             clearTimeout(timeoutId);
57928             if (isHidden) return;
57929
57930             updateProjection();
57931
57932             var dMini = utilGetDimensions(wrap),
57933                 zMini = ktoz(projection$$1.scale());
57934
57935             // setup tile container
57936             tiles = wrap
57937                 .selectAll('.map-in-map-tiles')
57938                 .data([0]);
57939
57940             tiles = tiles.enter()
57941                 .append('div')
57942                 .attr('class', 'map-in-map-tiles')
57943                 .merge(tiles);
57944
57945             // redraw background
57946             backgroundLayer
57947                 .source(context.background().baseLayerSource())
57948                 .projection(projection$$1)
57949                 .dimensions(dMini);
57950
57951             var background = tiles
57952                 .selectAll('.map-in-map-background')
57953                 .data([0]);
57954
57955             background.enter()
57956                 .append('div')
57957                 .attr('class', 'map-in-map-background')
57958                 .merge(background)
57959                 .call(backgroundLayer);
57960
57961
57962             // redraw overlay
57963             var overlaySources = context.background().overlayLayerSources();
57964             var activeOverlayLayers = [];
57965             for (var i = 0; i < overlaySources.length; i++) {
57966                 if (overlaySources[i].validZoom(zMini)) {
57967                     if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
57968                     activeOverlayLayers.push(overlayLayers[i]
57969                         .source(overlaySources[i])
57970                         .projection(projection$$1)
57971                         .dimensions(dMini));
57972                 }
57973             }
57974
57975             var overlay = tiles
57976                 .selectAll('.map-in-map-overlay')
57977                 .data([0]);
57978
57979             overlay = overlay.enter()
57980                 .append('div')
57981                 .attr('class', 'map-in-map-overlay')
57982                 .merge(overlay);
57983
57984
57985             var overlays = overlay
57986                 .selectAll('div')
57987                 .data(activeOverlayLayers, function(d) { return d.source().name(); });
57988
57989             overlays.exit()
57990                 .remove();
57991
57992             overlays = overlays.enter()
57993                 .append('div')
57994                 .merge(overlays)
57995                 .each(function(layer) { select(this).call(layer); });
57996
57997
57998             var dataLayers = tiles
57999                 .selectAll('.map-in-map-data')
58000                 .data([0]);
58001
58002             dataLayers.exit()
58003                 .remove();
58004
58005             dataLayers = dataLayers.enter()
58006                 .append('svg')
58007                 .attr('class', 'map-in-map-data')
58008                 .merge(dataLayers)
58009                 .call(gpxLayer)
58010                 .call(debugLayer);
58011
58012
58013             // redraw viewport bounding box
58014             if (gesture !== 'pan') {
58015                 var getPath = index$4(projection$$1),
58016                     bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
58017
58018                 viewport = wrap.selectAll('.map-in-map-viewport')
58019                     .data([0]);
58020
58021                 viewport = viewport.enter()
58022                     .append('svg')
58023                     .attr('class', 'map-in-map-viewport')
58024                     .merge(viewport);
58025
58026
58027                 var path$$1 = viewport.selectAll('.map-in-map-bbox')
58028                     .data([bbox]);
58029
58030                 path$$1.enter()
58031                     .append('path')
58032                     .attr('class', 'map-in-map-bbox')
58033                     .merge(path$$1)
58034                     .attr('d', getPath)
58035                     .classed('thick', function(d) { return getPath.area(d) < 30; });
58036             }
58037         }
58038
58039
58040         function queueRedraw() {
58041             clearTimeout(timeoutId);
58042             timeoutId = setTimeout(function() { redraw(); }, 750);
58043         }
58044
58045
58046         function toggle() {
58047             if (event) event.preventDefault();
58048
58049             isHidden = !isHidden;
58050
58051             var label = select('.minimap-toggle');
58052             label.classed('active', !isHidden)
58053                 .select('input').property('checked', !isHidden);
58054
58055             if (isHidden) {
58056                 wrap
58057                     .style('display', 'block')
58058                     .style('opacity', '1')
58059                     .transition()
58060                     .duration(200)
58061                     .style('opacity', '0')
58062                     .on('end', function() {
58063                         selection$$1.selectAll('.map-in-map')
58064                             .style('display', 'none');
58065                     });
58066             } else {
58067                 wrap
58068                     .style('display', 'block')
58069                     .style('opacity', '0')
58070                     .transition()
58071                     .duration(200)
58072                     .style('opacity', '1')
58073                     .on('end', function() {
58074                         redraw();
58075                     });
58076             }
58077         }
58078
58079
58080         uiMapInMap.toggle = toggle;
58081
58082         wrap = selection$$1.selectAll('.map-in-map')
58083             .data([0]);
58084
58085         wrap = wrap.enter()
58086             .append('div')
58087             .attr('class', 'map-in-map')
58088             .style('display', (isHidden ? 'none' : 'block'))
58089             .call(zoom$$1)
58090             .on('dblclick.zoom', null)
58091             .merge(wrap);
58092
58093         context.map()
58094             .on('drawn.map-in-map', function(drawn) {
58095                 if (drawn.full === true) {
58096                     redraw();
58097                 }
58098             });
58099
58100         redraw();
58101
58102         var keybinding = d3keybinding('map-in-map')
58103             .on(t('background.minimap.key'), toggle);
58104
58105         select(document)
58106             .call(keybinding);
58107     }
58108
58109     return map_in_map;
58110 }
58111
58112 function uiTooltipHtml(text, key, heading) {
58113     var s = '';
58114
58115     if (heading) {
58116         s += '<div class="tooltip-heading"><span>' + heading + '</span></div>';
58117     }
58118     if (text) {
58119         s += '<div class="tooltip-text"><span>' + text + '</span></div>';
58120     }
58121     if (key) {
58122         s += '<div class="keyhint-wrap"><span>' + t('tooltip_keyhint') + '</span>' +
58123             '<span class="keyhint">' + key + '</span></div>';
58124     }
58125
58126     return s;
58127 }
58128
58129 function uiBackground(context) {
58130     var key = t('background.key'),
58131         detected = utilDetect(),
58132         opacities = [1, 0.75, 0.5, 0.25],
58133         directions = [
58134             ['right', [0.5, 0]],
58135             ['top', [0, -0.5]],
58136             ['left', [-0.5, 0]],
58137             ['bottom', [0, 0.5]]],
58138         opacityDefault = (context.storage('background-opacity') !== null) ?
58139             (+context.storage('background-opacity')) : 1.0,
58140         customSource = context.background().findSource('custom'),
58141         previous;
58142
58143     // Can be 0 from <1.3.0 use or due to issue #1923.
58144     if (opacityDefault === 0) opacityDefault = 1.0;
58145
58146
58147     function background(selection$$1) {
58148
58149         function sortSources(a, b) {
58150             return a.best() && !b.best() ? -1
58151                 : b.best() && !a.best() ? 1
58152                 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
58153         }
58154
58155
58156         function setOpacity(d) {
58157             var bg = context.container().selectAll('.layer-background')
58158                 .transition()
58159                 .style('opacity', d)
58160                 .attr('data-opacity', d);
58161
58162             if (!detected.opera) {
58163                 utilSetTransform(bg, 0, 0);
58164             }
58165
58166             opacityList.selectAll('li')
58167                 .classed('active', function(_) { return _ === d; });
58168
58169             context.storage('background-opacity', d);
58170         }
58171
58172
58173         function setTooltips(selection$$1) {
58174             selection$$1.each(function(d, i, nodes) {
58175                 var item = select(this).select('label'),
58176                     span = item.select('span'),
58177                     placement = (i < nodes.length / 2) ? 'bottom' : 'top',
58178                     description = d.description(),
58179                     isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
58180
58181                 if (d === previous) {
58182                     item.call(tooltip()
58183                         .placement(placement)
58184                         .html(true)
58185                         .title(function() {
58186                             var tip = '<div>' + t('background.switch') + '</div>';
58187                             return uiTooltipHtml(tip, uiCmd('⌘' + key));
58188                         })
58189                     );
58190                 } else if (description || isOverflowing) {
58191                     item.call(tooltip()
58192                         .placement(placement)
58193                         .title(description || d.name())
58194                     );
58195                 } else {
58196                     item.call(tooltip().destroy);
58197                 }
58198             });
58199         }
58200
58201
58202         function selectLayer() {
58203             function active$$1(d) {
58204                 return context.background().showsLayer(d);
58205             }
58206
58207             content.selectAll('.layer')
58208                 .classed('active', active$$1)
58209                 .classed('switch', function(d) { return d === previous; })
58210                 .call(setTooltips)
58211                 .selectAll('input')
58212                 .property('checked', active$$1);
58213         }
58214
58215
58216         function clickSetSource(d) {
58217             if (d.id === 'custom' && !d.template()) {
58218                 return editCustom();
58219             }
58220
58221             event.preventDefault();
58222             previous = context.background().baseLayerSource();
58223             context.background().baseLayerSource(d);
58224             selectLayer();
58225             document.activeElement.blur();
58226         }
58227
58228
58229         function editCustom() {
58230             event.preventDefault();
58231             var example = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png';
58232             var template = window.prompt(
58233                 t('background.custom_prompt', { example: example }),
58234                 customSource.template() || example
58235             );
58236
58237             if (template) {
58238                 context.storage('background-custom-template', template);
58239                 customSource.template(template);
58240                 clickSetSource(customSource);
58241             } else {
58242                 selectLayer();
58243             }
58244         }
58245
58246
58247         function clickSetOverlay(d) {
58248             event.preventDefault();
58249             context.background().toggleOverlayLayer(d);
58250             selectLayer();
58251             document.activeElement.blur();
58252         }
58253
58254
58255         function drawList(layerList, type, change, filter) {
58256             var sources = context.background()
58257                 .sources(context.map().extent())
58258                 .filter(filter);
58259
58260             var layerLinks = layerList.selectAll('li.layer')
58261                 .data(sources, function(d) { return d.name(); });
58262
58263             layerLinks.exit()
58264                 .remove();
58265
58266             var enter = layerLinks.enter()
58267                 .append('li')
58268                 .attr('class', 'layer')
58269                 .classed('layer-custom', function(d) { return d.id === 'custom'; })
58270                 .classed('best', function(d) { return d.best(); });
58271
58272             enter.filter(function(d) { return d.id === 'custom'; })
58273                 .append('button')
58274                 .attr('class', 'layer-browse')
58275                 .call(tooltip()
58276                     .title(t('background.custom_button'))
58277                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
58278                 .on('click', editCustom)
58279                 .call(svgIcon('#icon-search'));
58280
58281             enter.filter(function(d) { return d.best(); })
58282                 .append('div')
58283                 .attr('class', 'best')
58284                 .call(tooltip()
58285                     .title(t('background.best_imagery'))
58286                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
58287                 .append('span')
58288                 .html('&#9733;');
58289
58290             var label = enter
58291                 .append('label');
58292
58293             label
58294                 .append('input')
58295                 .attr('type', type)
58296                 .attr('name', 'layers')
58297                 .on('change', change);
58298
58299             label
58300                 .append('span')
58301                 .text(function(d) { return d.name(); });
58302
58303
58304             layerList.selectAll('li.layer')
58305                 .sort(sortSources)
58306                 .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
58307         }
58308
58309
58310         function update() {
58311             backgroundList.call(drawList, 'radio', clickSetSource, function(d) { return !d.overlay; });
58312             overlayList.call(drawList, 'checkbox', clickSetOverlay, function(d) { return d.overlay; });
58313
58314             selectLayer();
58315             updateOffsetVal();
58316         }
58317
58318
58319         function updateOffsetVal() {
58320             var meters = geoOffsetToMeters(context.background().offset()),
58321                 x = +meters[0].toFixed(2),
58322                 y = +meters[1].toFixed(2);
58323
58324             selectAll('.nudge-inner-rect')
58325                 .select('input')
58326                 .classed('error', false)
58327                 .property('value', x + ', ' + y);
58328
58329             selectAll('.nudge-reset')
58330                 .classed('disabled', function() {
58331                     return (x === 0 && y === 0);
58332                 });
58333         }
58334
58335
58336         function resetOffset() {
58337             if (event.button !== 0) return;
58338             context.background().offset([0, 0]);
58339             updateOffsetVal();
58340         }
58341
58342
58343         function nudge(d) {
58344             context.background().nudge(d, context.map().zoom());
58345             updateOffsetVal();
58346         }
58347
58348
58349         function buttonOffset(d) {
58350             if (event.button !== 0) return;
58351             var timeout = window.setTimeout(function() {
58352                     interval = window.setInterval(nudge.bind(null, d), 100);
58353                 }, 500),
58354                 interval;
58355
58356             function doneNudge() {
58357                 window.clearTimeout(timeout);
58358                 window.clearInterval(interval);
58359                 select(window)
58360                     .on('mouseup.buttonoffset', null, true)
58361                     .on('mousedown.buttonoffset', null, true);
58362             }
58363
58364             select(window)
58365                 .on('mouseup.buttonoffset', doneNudge, true)
58366                 .on('mousedown.buttonoffset', doneNudge, true);
58367
58368             nudge(d);
58369         }
58370
58371
58372         function inputOffset() {
58373             if (event.button !== 0) return;
58374             var input = select(this);
58375             var d = input.node().value;
58376
58377             if (d === '') return resetOffset();
58378
58379             d = d.replace(/;/g, ',').split(',').map(function(n) {
58380                 // if n is NaN, it will always get mapped to false.
58381                 return !isNaN(n) && n;
58382             });
58383
58384             if (d.length !== 2 || !d[0] || !d[1]) {
58385                 input.classed('error', true);
58386                 return;
58387             }
58388
58389             context.background().offset(geoMetersToOffset(d));
58390             updateOffsetVal();
58391         }
58392
58393
58394         function dragOffset() {
58395             if (event.button !== 0) return;
58396             var origin = [event.clientX, event.clientY];
58397
58398             context.container()
58399                 .append('div')
58400                 .attr('class', 'nudge-surface');
58401
58402             select(window)
58403                 .on('mousemove.offset', function() {
58404                     var latest = [event.clientX, event.clientY];
58405                     var d = [
58406                         -(origin[0] - latest[0]) / 4,
58407                         -(origin[1] - latest[1]) / 4
58408                     ];
58409
58410                     origin = latest;
58411                     nudge(d);
58412                 })
58413                 .on('mouseup.offset', function() {
58414                     if (event.button !== 0) return;
58415                     selectAll('.nudge-surface')
58416                         .remove();
58417
58418                     select(window)
58419                         .on('mousemove.offset', null)
58420                         .on('mouseup.offset', null);
58421                 });
58422
58423             event.preventDefault();
58424         }
58425
58426
58427         function hide() {
58428             setVisible(false);
58429         }
58430
58431
58432         function toggle() {
58433             if (event) {
58434                 event.preventDefault();
58435             }
58436             tooltipBehavior.hide(button);
58437             setVisible(!button.classed('active'));
58438         }
58439
58440
58441         function quickSwitch() {
58442             if (event) {
58443                 event.stopImmediatePropagation();
58444                 event.preventDefault();
58445             }
58446             if (previous) {
58447                 clickSetSource(previous);
58448             }
58449         }
58450
58451
58452         function setVisible(show) {
58453             if (show !== shown) {
58454                 button.classed('active', show);
58455                 shown = show;
58456
58457                 if (show) {
58458                     selection$$1
58459                         .on('mousedown.background-inside', function() {
58460                             event.stopPropagation();
58461                         });
58462
58463                     content
58464                         .style('display', 'block')
58465                         .style('right', '-300px')
58466                         .transition()
58467                         .duration(200)
58468                         .style('right', '0px');
58469
58470                     content.selectAll('.layer')
58471                         .call(setTooltips);
58472
58473                 } else {
58474                     content
58475                         .style('display', 'block')
58476                         .style('right', '0px')
58477                         .transition()
58478                         .duration(200)
58479                         .style('right', '-300px')
58480                         .on('end', function() {
58481                             select(this).style('display', 'none');
58482                         });
58483
58484                     selection$$1
58485                         .on('mousedown.background-inside', null);
58486                 }
58487             }
58488         }
58489
58490
58491         var content = selection$$1
58492                 .append('div')
58493                 .attr('class', 'fillL map-overlay col3 content hide'),
58494             tooltipBehavior = tooltip()
58495                 .placement((textDirection === 'rtl') ? 'right' : 'left')
58496                 .html(true)
58497                 .title(uiTooltipHtml(t('background.description'), key)),
58498             button = selection$$1
58499                 .append('button')
58500                 .attr('tabindex', -1)
58501                 .on('click', toggle)
58502                 .call(svgIcon('#icon-layers', 'light'))
58503                 .call(tooltipBehavior),
58504             shown = false;
58505
58506
58507         /* opacity switcher */
58508
58509         var opawrap = content
58510                 .append('div')
58511                 .attr('class', 'opacity-options-wrapper');
58512
58513         opawrap
58514             .append('h4')
58515             .text(t('background.title'));
58516
58517         var opacityList = opawrap
58518             .append('ul')
58519             .attr('class', 'opacity-options');
58520
58521         opacityList.selectAll('div.opacity')
58522             .data(opacities)
58523             .enter()
58524             .append('li')
58525             .attr('data-original-title', function(d) {
58526                 return t('background.percent_brightness', { opacity: (d * 100) });
58527             })
58528             .on('click.set-opacity', setOpacity)
58529             .html('<div class="select-box"></div>')
58530             .call(tooltip()
58531                 .placement((textDirection === 'rtl') ? 'right' : 'left'))
58532             .append('div')
58533             .attr('class', 'opacity')
58534             .style('opacity', function(d) { return 1.25 - d; });
58535
58536
58537         /* background list */
58538
58539         var backgroundList = content
58540             .append('ul')
58541             .attr('class', 'layer-list')
58542             .attr('dir', 'auto');
58543
58544         content
58545             .append('div')
58546             .attr('class', 'imagery-faq')
58547             .append('a')
58548             .attr('target', '_blank')
58549             .attr('tabindex', -1)
58550             .call(svgIcon('#icon-out-link', 'inline'))
58551             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
58552             .append('span')
58553             .text(t('background.imagery_source_faq'));
58554
58555
58556         /* overlay list */
58557
58558         var overlayList = content
58559             .append('ul')
58560             .attr('class', 'layer-list');
58561
58562         var controls = content
58563             .append('div')
58564             .attr('class', 'controls-list');
58565
58566
58567         /* minimap toggle */
58568
58569         var minimapLabel = controls
58570             .append('label')
58571             .call(tooltip()
58572                 .html(true)
58573                 .title(uiTooltipHtml(t('background.minimap.tooltip'), t('background.minimap.key')))
58574                 .placement('top')
58575             );
58576
58577         minimapLabel
58578             .classed('minimap-toggle', true)
58579             .append('input')
58580             .attr('type', 'checkbox')
58581             .on('change', function() {
58582                 uiMapInMap.toggle();
58583                 event.preventDefault();
58584             });
58585
58586         minimapLabel
58587             .append('span')
58588             .text(t('background.minimap.description'));
58589
58590
58591         /* imagery offset controls */
58592
58593         var adjustments = content
58594             .append('div')
58595             .attr('class', 'adjustments');
58596
58597         adjustments
58598             .append('a')
58599             .text(t('background.fix_misalignment'))
58600             .attr('href', '#')
58601             .classed('hide-toggle', true)
58602             .classed('expanded', false)
58603             .on('click', function() {
58604                 if (event.button !== 0) return;
58605                 var exp = select(this).classed('expanded');
58606                 nudgeContainer.style('display', exp ? 'none' : 'block');
58607                 select(this).classed('expanded', !exp);
58608                 event.preventDefault();
58609             });
58610
58611         var nudgeContainer = adjustments
58612             .append('div')
58613             .attr('class', 'nudge-container cf')
58614             .style('display', 'none');
58615
58616         nudgeContainer
58617             .append('div')
58618             .attr('class', 'nudge-instructions')
58619             .text(t('background.offset'));
58620
58621         var nudgeRect = nudgeContainer
58622             .append('div')
58623             .attr('class', 'nudge-outer-rect')
58624             .on('mousedown', dragOffset);
58625
58626         nudgeRect
58627             .append('div')
58628             .attr('class', 'nudge-inner-rect')
58629             .append('input')
58630             .on('change', inputOffset)
58631             .on('mousedown', function() {
58632                 if (event.button !== 0) return;
58633                 event.stopPropagation();
58634             });
58635
58636         nudgeContainer
58637             .append('div')
58638             .selectAll('button')
58639             .data(directions).enter()
58640             .append('button')
58641             .attr('class', function(d) { return d[0] + ' nudge'; })
58642             .on('mousedown', function(d) {
58643                 if (event.button !== 0) return;
58644                 buttonOffset(d[1]);
58645             });
58646
58647         nudgeContainer
58648             .append('button')
58649             .attr('title', t('background.reset'))
58650             .attr('class', 'nudge-reset disabled')
58651             .on('click', resetOffset)
58652             .call(
58653                 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
58654             );
58655
58656         context.map()
58657             .on('move.background-update', lodash.debounce(utilCallWhenIdle(update), 1000));
58658
58659         context.background()
58660             .on('change.background-update', update);
58661
58662
58663         update();
58664         setOpacity(opacityDefault);
58665
58666         var keybinding = d3keybinding('background')
58667             .on(key, toggle)
58668             .on(uiCmd('⌘' + key), quickSwitch)
58669             .on([t('map_data.key'), t('help.key')], hide);
58670
58671         select(document)
58672             .call(keybinding);
58673
58674         context.surface().on('mousedown.background-outside', hide);
58675         context.container().on('mousedown.background-outside', hide);
58676     }
58677
58678     return background;
58679 }
58680
58681 function uiContributors(context) {
58682     var osm = context.connection(),
58683         debouncedUpdate = lodash.debounce(function() { update(); }, 1000),
58684         limit = 4,
58685         hidden = false,
58686         wrap = select(null);
58687
58688
58689     function update() {
58690         if (!osm) return;
58691
58692         var users = {},
58693             entities = context.intersects(context.map().extent());
58694
58695         entities.forEach(function(entity) {
58696             if (entity && entity.user) users[entity.user] = true;
58697         });
58698
58699         var u = Object.keys(users),
58700             subset = u.slice(0, u.length > limit ? limit - 1 : limit);
58701
58702         wrap.html('')
58703             .call(svgIcon('#icon-nearby', 'pre-text light'));
58704
58705         var userList = select(document.createElement('span'));
58706
58707         userList.selectAll()
58708             .data(subset)
58709             .enter()
58710             .append('a')
58711             .attr('class', 'user-link')
58712             .attr('href', function(d) { return osm.userURL(d); })
58713             .attr('target', '_blank')
58714             .attr('tabindex', -1)
58715             .text(String);
58716
58717         if (u.length > limit) {
58718             var count = select(document.createElement('span'));
58719
58720             count.append('a')
58721                 .attr('target', '_blank')
58722                 .attr('tabindex', -1)
58723                 .attr('href', function() {
58724                     return osm.changesetsURL(context.map().center(), context.map().zoom());
58725                 })
58726                 .text(u.length - limit + 1);
58727
58728             wrap.append('span')
58729                 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
58730
58731         } else {
58732             wrap.append('span')
58733                 .html(t('contributors.list', { users: userList.html() }));
58734         }
58735
58736         if (!u.length) {
58737             hidden = true;
58738             wrap
58739                 .transition()
58740                 .style('opacity', 0);
58741
58742         } else if (hidden) {
58743             wrap
58744                 .transition()
58745                 .style('opacity', 1);
58746         }
58747     }
58748
58749
58750     return function(selection$$1) {
58751         if (!osm) return;
58752         wrap = selection$$1;
58753         update();
58754
58755         osm.on('loaded.contributors', debouncedUpdate);
58756         context.map().on('move.contributors', debouncedUpdate);
58757     };
58758 }
58759
58760 function uiFeatureInfo(context) {
58761     function update(selection$$1) {
58762         var features = context.features(),
58763             stats = features.stats(),
58764             count = 0,
58765             hiddenList = lodash.compact(lodash.map(features.hidden(), function(k) {
58766                 if (stats[k]) {
58767                     count += stats[k];
58768                     return String(stats[k]) + ' ' + t('feature.' + k + '.description');
58769                 }
58770             }));
58771
58772         selection$$1.html('');
58773
58774         if (hiddenList.length) {
58775             var tooltipBehavior = tooltip()
58776                     .placement('top')
58777                     .html(true)
58778                     .title(function() {
58779                         return uiTooltipHtml(hiddenList.join('<br/>'));
58780                     });
58781
58782             var warning = selection$$1.append('a')
58783                 .attr('href', '#')
58784                 .attr('tabindex', -1)
58785                 .html(t('feature_info.hidden_warning', { count: count }))
58786                 .call(tooltipBehavior)
58787                 .on('click', function() {
58788                     tooltipBehavior.hide(warning);
58789                     // open map data panel?
58790                     event.preventDefault();
58791                 });
58792         }
58793
58794         selection$$1
58795             .classed('hide', !hiddenList.length);
58796     }
58797
58798
58799     return function(selection$$1) {
58800         update(selection$$1);
58801
58802         context.features().on('change.feature_info', function() {
58803             update(selection$$1);
58804         });
58805     };
58806 }
58807
58808 function uiFullScreen(context) {
58809     var element = context.container().node(),
58810         keybinding = d3keybinding('full-screen');
58811         // button;
58812
58813
58814     function getFullScreenFn() {
58815         if (element.requestFullscreen) {
58816             return element.requestFullscreen;
58817         } else if (element.msRequestFullscreen) {
58818             return element.msRequestFullscreen;
58819         } else if (element.mozRequestFullScreen) {
58820             return element.mozRequestFullScreen;
58821         } else if (element.webkitRequestFullscreen) {
58822             return element.webkitRequestFullscreen;
58823         }
58824     }
58825
58826
58827     function getExitFullScreenFn() {
58828         if (document.exitFullscreen) {
58829             return document.exitFullscreen;
58830         } else if (document.msExitFullscreen) {
58831             return document.msExitFullscreen;
58832         } else if (document.mozCancelFullScreen) {
58833             return document.mozCancelFullScreen;
58834         } else if (document.webkitExitFullscreen) {
58835             return document.webkitExitFullscreen;
58836         }
58837     }
58838
58839
58840     function isFullScreen() {
58841         return document.fullscreenElement ||
58842             document.mozFullScreenElement ||
58843             document.webkitFullscreenElement ||
58844             document.msFullscreenElement;
58845     }
58846
58847
58848     function isSupported() {
58849         return !!getFullScreenFn();
58850     }
58851
58852
58853     function fullScreen() {
58854         event.preventDefault();
58855         if (!isFullScreen()) {
58856             // button.classed('active', true);
58857             getFullScreenFn().apply(element);
58858         } else {
58859             // button.classed('active', false);
58860             getExitFullScreenFn().apply(document);
58861         }
58862     }
58863
58864
58865     return function() { // selection) {
58866         if (!isSupported())
58867             return;
58868
58869         // button = selection.append('button')
58870         //     .attr('title', t('full_screen'))
58871         //     .attr('tabindex', -1)
58872         //     .on('click', fullScreen)
58873         //     .call(tooltip);
58874
58875         // button.append('span')
58876         //     .attr('class', 'icon full-screen');
58877
58878         var detected = utilDetect();
58879         var keys$$1 = detected.os === 'mac' ? [uiCmd('⌃⌘F'), 'f11'] : ['f11'];
58880         keybinding.on(keys$$1, fullScreen);
58881
58882         select(document)
58883             .call(keybinding);
58884     };
58885 }
58886
58887 function uiModal(selection$$1, blocking) {
58888     var keybinding = d3keybinding('modal');
58889     var previous = selection$$1.select('div.modal');
58890     var animate = previous.empty();
58891
58892     previous.transition()
58893         .duration(200)
58894         .style('opacity', 0)
58895         .remove();
58896
58897     var shaded = selection$$1
58898         .append('div')
58899         .attr('class', 'shaded')
58900         .style('opacity', 0);
58901
58902     shaded.close = function() {
58903         shaded
58904             .transition()
58905             .duration(200)
58906             .style('opacity',0)
58907             .remove();
58908
58909         modal
58910             .transition()
58911             .duration(200)
58912             .style('top','0px');
58913
58914         keybinding.off();
58915     };
58916
58917
58918     var modal = shaded
58919         .append('div')
58920         .attr('class', 'modal fillL col6');
58921
58922     if (!blocking) {
58923         shaded.on('click.remove-modal', function() {
58924             if (event.target === this) {
58925                 shaded.close();
58926             }
58927         });
58928
58929         modal.append('button')
58930             .attr('class', 'close')
58931             .on('click', shaded.close)
58932             .call(svgIcon('#icon-close'));
58933
58934         keybinding
58935             .on('⌫', shaded.close)
58936             .on('⎋', shaded.close);
58937
58938         select(document)
58939             .call(keybinding);
58940     }
58941
58942     modal
58943         .append('div')
58944         .attr('class', 'content');
58945
58946     if (animate) {
58947         shaded.transition().style('opacity', 1);
58948     } else {
58949         shaded.style('opacity', 1);
58950     }
58951
58952
58953     return shaded;
58954 }
58955
58956 function uiLoading(context) {
58957     var message = '',
58958         blocking = false,
58959         modalSelection;
58960
58961
58962     var loading = function(selection) {
58963         modalSelection = uiModal(selection, blocking);
58964
58965         var loadertext = modalSelection.select('.content')
58966             .classed('loading-modal', true)
58967             .append('div')
58968             .attr('class', 'modal-section fillL');
58969
58970         loadertext
58971             .append('img')
58972             .attr('class', 'loader')
58973             .attr('src', context.imagePath('loader-white.gif'));
58974
58975         loadertext
58976             .append('h3')
58977             .text(message);
58978
58979         modalSelection.select('button.close')
58980             .attr('class', 'hide');
58981
58982         return loading;
58983     };
58984
58985
58986     loading.message = function(_) {
58987         if (!arguments.length) return message;
58988         message = _;
58989         return loading;
58990     };
58991
58992
58993     loading.blocking = function(_) {
58994         if (!arguments.length) return blocking;
58995         blocking = _;
58996         return loading;
58997     };
58998
58999
59000     loading.close = function() {
59001         modalSelection.remove();
59002     };
59003
59004
59005     return loading;
59006 }
59007
59008 function uiGeolocate(context) {
59009     var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
59010         locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
59011         timeoutId;
59012
59013
59014     function click() {
59015         if (context.inIntro()) return;
59016         context.enter(modeBrowse(context));
59017         context.container().call(locating);
59018         navigator.geolocation.getCurrentPosition(success, error, geoOptions);
59019
59020         // This timeout ensures that we still call finish() even if
59021         // the user declines to share their location in Firefox
59022         timeoutId = setTimeout(finish, 10000 /* 10sec */ );
59023     }
59024
59025
59026     function success(position) {
59027         var map = context.map(),
59028             extent = geoExtent$$1([position.coords.longitude, position.coords.latitude])
59029                 .padByMeters(position.coords.accuracy);
59030
59031         map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
59032         finish();
59033     }
59034
59035
59036     function error() {
59037         finish();
59038     }
59039
59040
59041     function finish() {
59042         locating.close();  // unblock ui
59043         if (timeoutId) { clearTimeout(timeoutId); }
59044         timeoutId = undefined;
59045     }
59046
59047
59048     return function(selection) {
59049         if (!navigator.geolocation) return;
59050
59051         selection
59052             .append('button')
59053             .attr('tabindex', -1)
59054             .attr('title', t('geolocate.title'))
59055             .on('click', click)
59056             .call(svgIcon('#icon-geolocate', 'light'))
59057             .call(tooltip()
59058                 .placement((textDirection === 'rtl') ? 'right' : 'left'));
59059     };
59060 }
59061
59062 var marked = createCommonjsModule(function (module, exports) {
59063 /**
59064  * marked - a markdown parser
59065  * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
59066  * https://github.com/chjj/marked
59067  */
59068
59069 (function() {
59070
59071 /**
59072  * Block-Level Grammar
59073  */
59074
59075 var block = {
59076   newline: /^\n+/,
59077   code: /^( {4}[^\n]+\n*)+/,
59078   fences: noop,
59079   hr: /^( *[-*_]){3,} *(?:\n+|$)/,
59080   heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
59081   nptable: noop,
59082   lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
59083   blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
59084   list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
59085   html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
59086   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
59087   table: noop,
59088   paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
59089   text: /^[^\n]+/
59090 };
59091
59092 block.bullet = /(?:[*+-]|\d+\.)/;
59093 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
59094 block.item = replace(block.item, 'gm')
59095   (/bull/g, block.bullet)
59096   ();
59097
59098 block.list = replace(block.list)
59099   (/bull/g, block.bullet)
59100   ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
59101   ('def', '\\n+(?=' + block.def.source + ')')
59102   ();
59103
59104 block.blockquote = replace(block.blockquote)
59105   ('def', block.def)
59106   ();
59107
59108 block._tag = '(?!(?:'
59109   + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
59110   + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
59111   + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
59112
59113 block.html = replace(block.html)
59114   ('comment', /<!--[\s\S]*?-->/)
59115   ('closed', /<(tag)[\s\S]+?<\/\1>/)
59116   ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
59117   (/tag/g, block._tag)
59118   ();
59119
59120 block.paragraph = replace(block.paragraph)
59121   ('hr', block.hr)
59122   ('heading', block.heading)
59123   ('lheading', block.lheading)
59124   ('blockquote', block.blockquote)
59125   ('tag', '<' + block._tag)
59126   ('def', block.def)
59127   ();
59128
59129 /**
59130  * Normal Block Grammar
59131  */
59132
59133 block.normal = merge({}, block);
59134
59135 /**
59136  * GFM Block Grammar
59137  */
59138
59139 block.gfm = merge({}, block.normal, {
59140   fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
59141   paragraph: /^/,
59142   heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
59143 });
59144
59145 block.gfm.paragraph = replace(block.paragraph)
59146   ('(?!', '(?!'
59147     + block.gfm.fences.source.replace('\\1', '\\2') + '|'
59148     + block.list.source.replace('\\1', '\\3') + '|')
59149   ();
59150
59151 /**
59152  * GFM + Tables Block Grammar
59153  */
59154
59155 block.tables = merge({}, block.gfm, {
59156   nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
59157   table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
59158 });
59159
59160 /**
59161  * Block Lexer
59162  */
59163
59164 function Lexer(options) {
59165   this.tokens = [];
59166   this.tokens.links = {};
59167   this.options = options || marked.defaults;
59168   this.rules = block.normal;
59169
59170   if (this.options.gfm) {
59171     if (this.options.tables) {
59172       this.rules = block.tables;
59173     } else {
59174       this.rules = block.gfm;
59175     }
59176   }
59177 }
59178
59179 /**
59180  * Expose Block Rules
59181  */
59182
59183 Lexer.rules = block;
59184
59185 /**
59186  * Static Lex Method
59187  */
59188
59189 Lexer.lex = function(src, options) {
59190   var lexer = new Lexer(options);
59191   return lexer.lex(src);
59192 };
59193
59194 /**
59195  * Preprocessing
59196  */
59197
59198 Lexer.prototype.lex = function(src) {
59199   src = src
59200     .replace(/\r\n|\r/g, '\n')
59201     .replace(/\t/g, '    ')
59202     .replace(/\u00a0/g, ' ')
59203     .replace(/\u2424/g, '\n');
59204
59205   return this.token(src, true);
59206 };
59207
59208 /**
59209  * Lexing
59210  */
59211
59212 Lexer.prototype.token = function(src, top, bq) {
59213   var src = src.replace(/^ +$/gm, '')
59214     , next
59215     , loose
59216     , cap
59217     , bull
59218     , b
59219     , item
59220     , space
59221     , i
59222     , l;
59223
59224   while (src) {
59225     // newline
59226     if (cap = this.rules.newline.exec(src)) {
59227       src = src.substring(cap[0].length);
59228       if (cap[0].length > 1) {
59229         this.tokens.push({
59230           type: 'space'
59231         });
59232       }
59233     }
59234
59235     // code
59236     if (cap = this.rules.code.exec(src)) {
59237       src = src.substring(cap[0].length);
59238       cap = cap[0].replace(/^ {4}/gm, '');
59239       this.tokens.push({
59240         type: 'code',
59241         text: !this.options.pedantic
59242           ? cap.replace(/\n+$/, '')
59243           : cap
59244       });
59245       continue;
59246     }
59247
59248     // fences (gfm)
59249     if (cap = this.rules.fences.exec(src)) {
59250       src = src.substring(cap[0].length);
59251       this.tokens.push({
59252         type: 'code',
59253         lang: cap[2],
59254         text: cap[3] || ''
59255       });
59256       continue;
59257     }
59258
59259     // heading
59260     if (cap = this.rules.heading.exec(src)) {
59261       src = src.substring(cap[0].length);
59262       this.tokens.push({
59263         type: 'heading',
59264         depth: cap[1].length,
59265         text: cap[2]
59266       });
59267       continue;
59268     }
59269
59270     // table no leading pipe (gfm)
59271     if (top && (cap = this.rules.nptable.exec(src))) {
59272       src = src.substring(cap[0].length);
59273
59274       item = {
59275         type: 'table',
59276         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
59277         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
59278         cells: cap[3].replace(/\n$/, '').split('\n')
59279       };
59280
59281       for (i = 0; i < item.align.length; i++) {
59282         if (/^ *-+: *$/.test(item.align[i])) {
59283           item.align[i] = 'right';
59284         } else if (/^ *:-+: *$/.test(item.align[i])) {
59285           item.align[i] = 'center';
59286         } else if (/^ *:-+ *$/.test(item.align[i])) {
59287           item.align[i] = 'left';
59288         } else {
59289           item.align[i] = null;
59290         }
59291       }
59292
59293       for (i = 0; i < item.cells.length; i++) {
59294         item.cells[i] = item.cells[i].split(/ *\| */);
59295       }
59296
59297       this.tokens.push(item);
59298
59299       continue;
59300     }
59301
59302     // lheading
59303     if (cap = this.rules.lheading.exec(src)) {
59304       src = src.substring(cap[0].length);
59305       this.tokens.push({
59306         type: 'heading',
59307         depth: cap[2] === '=' ? 1 : 2,
59308         text: cap[1]
59309       });
59310       continue;
59311     }
59312
59313     // hr
59314     if (cap = this.rules.hr.exec(src)) {
59315       src = src.substring(cap[0].length);
59316       this.tokens.push({
59317         type: 'hr'
59318       });
59319       continue;
59320     }
59321
59322     // blockquote
59323     if (cap = this.rules.blockquote.exec(src)) {
59324       src = src.substring(cap[0].length);
59325
59326       this.tokens.push({
59327         type: 'blockquote_start'
59328       });
59329
59330       cap = cap[0].replace(/^ *> ?/gm, '');
59331
59332       // Pass `top` to keep the current
59333       // "toplevel" state. This is exactly
59334       // how markdown.pl works.
59335       this.token(cap, top, true);
59336
59337       this.tokens.push({
59338         type: 'blockquote_end'
59339       });
59340
59341       continue;
59342     }
59343
59344     // list
59345     if (cap = this.rules.list.exec(src)) {
59346       src = src.substring(cap[0].length);
59347       bull = cap[2];
59348
59349       this.tokens.push({
59350         type: 'list_start',
59351         ordered: bull.length > 1
59352       });
59353
59354       // Get each top-level item.
59355       cap = cap[0].match(this.rules.item);
59356
59357       next = false;
59358       l = cap.length;
59359       i = 0;
59360
59361       for (; i < l; i++) {
59362         item = cap[i];
59363
59364         // Remove the list item's bullet
59365         // so it is seen as the next token.
59366         space = item.length;
59367         item = item.replace(/^ *([*+-]|\d+\.) +/, '');
59368
59369         // Outdent whatever the
59370         // list item contains. Hacky.
59371         if (~item.indexOf('\n ')) {
59372           space -= item.length;
59373           item = !this.options.pedantic
59374             ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
59375             : item.replace(/^ {1,4}/gm, '');
59376         }
59377
59378         // Determine whether the next list item belongs here.
59379         // Backpedal if it does not belong in this list.
59380         if (this.options.smartLists && i !== l - 1) {
59381           b = block.bullet.exec(cap[i + 1])[0];
59382           if (bull !== b && !(bull.length > 1 && b.length > 1)) {
59383             src = cap.slice(i + 1).join('\n') + src;
59384             i = l - 1;
59385           }
59386         }
59387
59388         // Determine whether item is loose or not.
59389         // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
59390         // for discount behavior.
59391         loose = next || /\n\n(?!\s*$)/.test(item);
59392         if (i !== l - 1) {
59393           next = item.charAt(item.length - 1) === '\n';
59394           if (!loose) loose = next;
59395         }
59396
59397         this.tokens.push({
59398           type: loose
59399             ? 'loose_item_start'
59400             : 'list_item_start'
59401         });
59402
59403         // Recurse.
59404         this.token(item, false, bq);
59405
59406         this.tokens.push({
59407           type: 'list_item_end'
59408         });
59409       }
59410
59411       this.tokens.push({
59412         type: 'list_end'
59413       });
59414
59415       continue;
59416     }
59417
59418     // html
59419     if (cap = this.rules.html.exec(src)) {
59420       src = src.substring(cap[0].length);
59421       this.tokens.push({
59422         type: this.options.sanitize
59423           ? 'paragraph'
59424           : 'html',
59425         pre: !this.options.sanitizer
59426           && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
59427         text: cap[0]
59428       });
59429       continue;
59430     }
59431
59432     // def
59433     if ((!bq && top) && (cap = this.rules.def.exec(src))) {
59434       src = src.substring(cap[0].length);
59435       this.tokens.links[cap[1].toLowerCase()] = {
59436         href: cap[2],
59437         title: cap[3]
59438       };
59439       continue;
59440     }
59441
59442     // table (gfm)
59443     if (top && (cap = this.rules.table.exec(src))) {
59444       src = src.substring(cap[0].length);
59445
59446       item = {
59447         type: 'table',
59448         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
59449         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
59450         cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
59451       };
59452
59453       for (i = 0; i < item.align.length; i++) {
59454         if (/^ *-+: *$/.test(item.align[i])) {
59455           item.align[i] = 'right';
59456         } else if (/^ *:-+: *$/.test(item.align[i])) {
59457           item.align[i] = 'center';
59458         } else if (/^ *:-+ *$/.test(item.align[i])) {
59459           item.align[i] = 'left';
59460         } else {
59461           item.align[i] = null;
59462         }
59463       }
59464
59465       for (i = 0; i < item.cells.length; i++) {
59466         item.cells[i] = item.cells[i]
59467           .replace(/^ *\| *| *\| *$/g, '')
59468           .split(/ *\| */);
59469       }
59470
59471       this.tokens.push(item);
59472
59473       continue;
59474     }
59475
59476     // top-level paragraph
59477     if (top && (cap = this.rules.paragraph.exec(src))) {
59478       src = src.substring(cap[0].length);
59479       this.tokens.push({
59480         type: 'paragraph',
59481         text: cap[1].charAt(cap[1].length - 1) === '\n'
59482           ? cap[1].slice(0, -1)
59483           : cap[1]
59484       });
59485       continue;
59486     }
59487
59488     // text
59489     if (cap = this.rules.text.exec(src)) {
59490       // Top-level should never reach here.
59491       src = src.substring(cap[0].length);
59492       this.tokens.push({
59493         type: 'text',
59494         text: cap[0]
59495       });
59496       continue;
59497     }
59498
59499     if (src) {
59500       throw new
59501         Error('Infinite loop on byte: ' + src.charCodeAt(0));
59502     }
59503   }
59504
59505   return this.tokens;
59506 };
59507
59508 /**
59509  * Inline-Level Grammar
59510  */
59511
59512 var inline = {
59513   escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
59514   autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
59515   url: noop,
59516   tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
59517   link: /^!?\[(inside)\]\(href\)/,
59518   reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
59519   nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
59520   strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
59521   em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
59522   code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
59523   br: /^ {2,}\n(?!\s*$)/,
59524   del: noop,
59525   text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
59526 };
59527
59528 inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
59529 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
59530
59531 inline.link = replace(inline.link)
59532   ('inside', inline._inside)
59533   ('href', inline._href)
59534   ();
59535
59536 inline.reflink = replace(inline.reflink)
59537   ('inside', inline._inside)
59538   ();
59539
59540 /**
59541  * Normal Inline Grammar
59542  */
59543
59544 inline.normal = merge({}, inline);
59545
59546 /**
59547  * Pedantic Inline Grammar
59548  */
59549
59550 inline.pedantic = merge({}, inline.normal, {
59551   strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
59552   em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
59553 });
59554
59555 /**
59556  * GFM Inline Grammar
59557  */
59558
59559 inline.gfm = merge({}, inline.normal, {
59560   escape: replace(inline.escape)('])', '~|])')(),
59561   url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
59562   del: /^~~(?=\S)([\s\S]*?\S)~~/,
59563   text: replace(inline.text)
59564     (']|', '~]|')
59565     ('|', '|https?://|')
59566     ()
59567 });
59568
59569 /**
59570  * GFM + Line Breaks Inline Grammar
59571  */
59572
59573 inline.breaks = merge({}, inline.gfm, {
59574   br: replace(inline.br)('{2,}', '*')(),
59575   text: replace(inline.gfm.text)('{2,}', '*')()
59576 });
59577
59578 /**
59579  * Inline Lexer & Compiler
59580  */
59581
59582 function InlineLexer(links, options) {
59583   this.options = options || marked.defaults;
59584   this.links = links;
59585   this.rules = inline.normal;
59586   this.renderer = this.options.renderer || new Renderer;
59587   this.renderer.options = this.options;
59588
59589   if (!this.links) {
59590     throw new
59591       Error('Tokens array requires a `links` property.');
59592   }
59593
59594   if (this.options.gfm) {
59595     if (this.options.breaks) {
59596       this.rules = inline.breaks;
59597     } else {
59598       this.rules = inline.gfm;
59599     }
59600   } else if (this.options.pedantic) {
59601     this.rules = inline.pedantic;
59602   }
59603 }
59604
59605 /**
59606  * Expose Inline Rules
59607  */
59608
59609 InlineLexer.rules = inline;
59610
59611 /**
59612  * Static Lexing/Compiling Method
59613  */
59614
59615 InlineLexer.output = function(src, links, options) {
59616   var inline = new InlineLexer(links, options);
59617   return inline.output(src);
59618 };
59619
59620 /**
59621  * Lexing/Compiling
59622  */
59623
59624 InlineLexer.prototype.output = function(src) {
59625   var out = ''
59626     , link
59627     , text
59628     , href
59629     , cap;
59630
59631   while (src) {
59632     // escape
59633     if (cap = this.rules.escape.exec(src)) {
59634       src = src.substring(cap[0].length);
59635       out += cap[1];
59636       continue;
59637     }
59638
59639     // autolink
59640     if (cap = this.rules.autolink.exec(src)) {
59641       src = src.substring(cap[0].length);
59642       if (cap[2] === '@') {
59643         text = cap[1].charAt(6) === ':'
59644           ? this.mangle(cap[1].substring(7))
59645           : this.mangle(cap[1]);
59646         href = this.mangle('mailto:') + text;
59647       } else {
59648         text = escape(cap[1]);
59649         href = text;
59650       }
59651       out += this.renderer.link(href, null, text);
59652       continue;
59653     }
59654
59655     // url (gfm)
59656     if (!this.inLink && (cap = this.rules.url.exec(src))) {
59657       src = src.substring(cap[0].length);
59658       text = escape(cap[1]);
59659       href = text;
59660       out += this.renderer.link(href, null, text);
59661       continue;
59662     }
59663
59664     // tag
59665     if (cap = this.rules.tag.exec(src)) {
59666       if (!this.inLink && /^<a /i.test(cap[0])) {
59667         this.inLink = true;
59668       } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
59669         this.inLink = false;
59670       }
59671       src = src.substring(cap[0].length);
59672       out += this.options.sanitize
59673         ? this.options.sanitizer
59674           ? this.options.sanitizer(cap[0])
59675           : escape(cap[0])
59676         : cap[0];
59677       continue;
59678     }
59679
59680     // link
59681     if (cap = this.rules.link.exec(src)) {
59682       src = src.substring(cap[0].length);
59683       this.inLink = true;
59684       out += this.outputLink(cap, {
59685         href: cap[2],
59686         title: cap[3]
59687       });
59688       this.inLink = false;
59689       continue;
59690     }
59691
59692     // reflink, nolink
59693     if ((cap = this.rules.reflink.exec(src))
59694         || (cap = this.rules.nolink.exec(src))) {
59695       src = src.substring(cap[0].length);
59696       link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
59697       link = this.links[link.toLowerCase()];
59698       if (!link || !link.href) {
59699         out += cap[0].charAt(0);
59700         src = cap[0].substring(1) + src;
59701         continue;
59702       }
59703       this.inLink = true;
59704       out += this.outputLink(cap, link);
59705       this.inLink = false;
59706       continue;
59707     }
59708
59709     // strong
59710     if (cap = this.rules.strong.exec(src)) {
59711       src = src.substring(cap[0].length);
59712       out += this.renderer.strong(this.output(cap[2] || cap[1]));
59713       continue;
59714     }
59715
59716     // em
59717     if (cap = this.rules.em.exec(src)) {
59718       src = src.substring(cap[0].length);
59719       out += this.renderer.em(this.output(cap[2] || cap[1]));
59720       continue;
59721     }
59722
59723     // code
59724     if (cap = this.rules.code.exec(src)) {
59725       src = src.substring(cap[0].length);
59726       out += this.renderer.codespan(escape(cap[2], true));
59727       continue;
59728     }
59729
59730     // br
59731     if (cap = this.rules.br.exec(src)) {
59732       src = src.substring(cap[0].length);
59733       out += this.renderer.br();
59734       continue;
59735     }
59736
59737     // del (gfm)
59738     if (cap = this.rules.del.exec(src)) {
59739       src = src.substring(cap[0].length);
59740       out += this.renderer.del(this.output(cap[1]));
59741       continue;
59742     }
59743
59744     // text
59745     if (cap = this.rules.text.exec(src)) {
59746       src = src.substring(cap[0].length);
59747       out += this.renderer.text(escape(this.smartypants(cap[0])));
59748       continue;
59749     }
59750
59751     if (src) {
59752       throw new
59753         Error('Infinite loop on byte: ' + src.charCodeAt(0));
59754     }
59755   }
59756
59757   return out;
59758 };
59759
59760 /**
59761  * Compile Link
59762  */
59763
59764 InlineLexer.prototype.outputLink = function(cap, link) {
59765   var href = escape(link.href)
59766     , title = link.title ? escape(link.title) : null;
59767
59768   return cap[0].charAt(0) !== '!'
59769     ? this.renderer.link(href, title, this.output(cap[1]))
59770     : this.renderer.image(href, title, escape(cap[1]));
59771 };
59772
59773 /**
59774  * Smartypants Transformations
59775  */
59776
59777 InlineLexer.prototype.smartypants = function(text) {
59778   if (!this.options.smartypants) return text;
59779   return text
59780     // em-dashes
59781     .replace(/---/g, '\u2014')
59782     // en-dashes
59783     .replace(/--/g, '\u2013')
59784     // opening singles
59785     .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
59786     // closing singles & apostrophes
59787     .replace(/'/g, '\u2019')
59788     // opening doubles
59789     .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
59790     // closing doubles
59791     .replace(/"/g, '\u201d')
59792     // ellipses
59793     .replace(/\.{3}/g, '\u2026');
59794 };
59795
59796 /**
59797  * Mangle Links
59798  */
59799
59800 InlineLexer.prototype.mangle = function(text) {
59801   if (!this.options.mangle) return text;
59802   var out = ''
59803     , l = text.length
59804     , i = 0
59805     , ch;
59806
59807   for (; i < l; i++) {
59808     ch = text.charCodeAt(i);
59809     if (Math.random() > 0.5) {
59810       ch = 'x' + ch.toString(16);
59811     }
59812     out += '&#' + ch + ';';
59813   }
59814
59815   return out;
59816 };
59817
59818 /**
59819  * Renderer
59820  */
59821
59822 function Renderer(options) {
59823   this.options = options || {};
59824 }
59825
59826 Renderer.prototype.code = function(code, lang, escaped) {
59827   if (this.options.highlight) {
59828     var out = this.options.highlight(code, lang);
59829     if (out != null && out !== code) {
59830       escaped = true;
59831       code = out;
59832     }
59833   }
59834
59835   if (!lang) {
59836     return '<pre><code>'
59837       + (escaped ? code : escape(code, true))
59838       + '\n</code></pre>';
59839   }
59840
59841   return '<pre><code class="'
59842     + this.options.langPrefix
59843     + escape(lang, true)
59844     + '">'
59845     + (escaped ? code : escape(code, true))
59846     + '\n</code></pre>\n';
59847 };
59848
59849 Renderer.prototype.blockquote = function(quote) {
59850   return '<blockquote>\n' + quote + '</blockquote>\n';
59851 };
59852
59853 Renderer.prototype.html = function(html) {
59854   return html;
59855 };
59856
59857 Renderer.prototype.heading = function(text, level, raw) {
59858   return '<h'
59859     + level
59860     + ' id="'
59861     + this.options.headerPrefix
59862     + raw.toLowerCase().replace(/[^\w]+/g, '-')
59863     + '">'
59864     + text
59865     + '</h'
59866     + level
59867     + '>\n';
59868 };
59869
59870 Renderer.prototype.hr = function() {
59871   return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
59872 };
59873
59874 Renderer.prototype.list = function(body, ordered) {
59875   var type = ordered ? 'ol' : 'ul';
59876   return '<' + type + '>\n' + body + '</' + type + '>\n';
59877 };
59878
59879 Renderer.prototype.listitem = function(text) {
59880   return '<li>' + text + '</li>\n';
59881 };
59882
59883 Renderer.prototype.paragraph = function(text) {
59884   return '<p>' + text + '</p>\n';
59885 };
59886
59887 Renderer.prototype.table = function(header, body) {
59888   return '<table>\n'
59889     + '<thead>\n'
59890     + header
59891     + '</thead>\n'
59892     + '<tbody>\n'
59893     + body
59894     + '</tbody>\n'
59895     + '</table>\n';
59896 };
59897
59898 Renderer.prototype.tablerow = function(content) {
59899   return '<tr>\n' + content + '</tr>\n';
59900 };
59901
59902 Renderer.prototype.tablecell = function(content, flags) {
59903   var type = flags.header ? 'th' : 'td';
59904   var tag = flags.align
59905     ? '<' + type + ' style="text-align:' + flags.align + '">'
59906     : '<' + type + '>';
59907   return tag + content + '</' + type + '>\n';
59908 };
59909
59910 // span level renderer
59911 Renderer.prototype.strong = function(text) {
59912   return '<strong>' + text + '</strong>';
59913 };
59914
59915 Renderer.prototype.em = function(text) {
59916   return '<em>' + text + '</em>';
59917 };
59918
59919 Renderer.prototype.codespan = function(text) {
59920   return '<code>' + text + '</code>';
59921 };
59922
59923 Renderer.prototype.br = function() {
59924   return this.options.xhtml ? '<br/>' : '<br>';
59925 };
59926
59927 Renderer.prototype.del = function(text) {
59928   return '<del>' + text + '</del>';
59929 };
59930
59931 Renderer.prototype.link = function(href, title, text) {
59932   if (this.options.sanitize) {
59933     try {
59934       var prot = decodeURIComponent(unescape(href))
59935         .replace(/[^\w:]/g, '')
59936         .toLowerCase();
59937     } catch (e) {
59938       return '';
59939     }
59940     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
59941       return '';
59942     }
59943   }
59944   var out = '<a href="' + href + '"';
59945   if (title) {
59946     out += ' title="' + title + '"';
59947   }
59948   out += '>' + text + '</a>';
59949   return out;
59950 };
59951
59952 Renderer.prototype.image = function(href, title, text) {
59953   var out = '<img src="' + href + '" alt="' + text + '"';
59954   if (title) {
59955     out += ' title="' + title + '"';
59956   }
59957   out += this.options.xhtml ? '/>' : '>';
59958   return out;
59959 };
59960
59961 Renderer.prototype.text = function(text) {
59962   return text;
59963 };
59964
59965 /**
59966  * Parsing & Compiling
59967  */
59968
59969 function Parser(options) {
59970   this.tokens = [];
59971   this.token = null;
59972   this.options = options || marked.defaults;
59973   this.options.renderer = this.options.renderer || new Renderer;
59974   this.renderer = this.options.renderer;
59975   this.renderer.options = this.options;
59976 }
59977
59978 /**
59979  * Static Parse Method
59980  */
59981
59982 Parser.parse = function(src, options, renderer) {
59983   var parser = new Parser(options, renderer);
59984   return parser.parse(src);
59985 };
59986
59987 /**
59988  * Parse Loop
59989  */
59990
59991 Parser.prototype.parse = function(src) {
59992   this.inline = new InlineLexer(src.links, this.options, this.renderer);
59993   this.tokens = src.reverse();
59994
59995   var out = '';
59996   while (this.next()) {
59997     out += this.tok();
59998   }
59999
60000   return out;
60001 };
60002
60003 /**
60004  * Next Token
60005  */
60006
60007 Parser.prototype.next = function() {
60008   return this.token = this.tokens.pop();
60009 };
60010
60011 /**
60012  * Preview Next Token
60013  */
60014
60015 Parser.prototype.peek = function() {
60016   return this.tokens[this.tokens.length - 1] || 0;
60017 };
60018
60019 /**
60020  * Parse Text Tokens
60021  */
60022
60023 Parser.prototype.parseText = function() {
60024   var body = this.token.text;
60025
60026   while (this.peek().type === 'text') {
60027     body += '\n' + this.next().text;
60028   }
60029
60030   return this.inline.output(body);
60031 };
60032
60033 /**
60034  * Parse Current Token
60035  */
60036
60037 Parser.prototype.tok = function() {
60038   switch (this.token.type) {
60039     case 'space': {
60040       return '';
60041     }
60042     case 'hr': {
60043       return this.renderer.hr();
60044     }
60045     case 'heading': {
60046       return this.renderer.heading(
60047         this.inline.output(this.token.text),
60048         this.token.depth,
60049         this.token.text);
60050     }
60051     case 'code': {
60052       return this.renderer.code(this.token.text,
60053         this.token.lang,
60054         this.token.escaped);
60055     }
60056     case 'table': {
60057       var header = ''
60058         , body = ''
60059         , i
60060         , row
60061         , cell
60062         , flags
60063         , j;
60064
60065       // header
60066       cell = '';
60067       for (i = 0; i < this.token.header.length; i++) {
60068         flags = { header: true, align: this.token.align[i] };
60069         cell += this.renderer.tablecell(
60070           this.inline.output(this.token.header[i]),
60071           { header: true, align: this.token.align[i] }
60072         );
60073       }
60074       header += this.renderer.tablerow(cell);
60075
60076       for (i = 0; i < this.token.cells.length; i++) {
60077         row = this.token.cells[i];
60078
60079         cell = '';
60080         for (j = 0; j < row.length; j++) {
60081           cell += this.renderer.tablecell(
60082             this.inline.output(row[j]),
60083             { header: false, align: this.token.align[j] }
60084           );
60085         }
60086
60087         body += this.renderer.tablerow(cell);
60088       }
60089       return this.renderer.table(header, body);
60090     }
60091     case 'blockquote_start': {
60092       var body = '';
60093
60094       while (this.next().type !== 'blockquote_end') {
60095         body += this.tok();
60096       }
60097
60098       return this.renderer.blockquote(body);
60099     }
60100     case 'list_start': {
60101       var body = ''
60102         , ordered = this.token.ordered;
60103
60104       while (this.next().type !== 'list_end') {
60105         body += this.tok();
60106       }
60107
60108       return this.renderer.list(body, ordered);
60109     }
60110     case 'list_item_start': {
60111       var body = '';
60112
60113       while (this.next().type !== 'list_item_end') {
60114         body += this.token.type === 'text'
60115           ? this.parseText()
60116           : this.tok();
60117       }
60118
60119       return this.renderer.listitem(body);
60120     }
60121     case 'loose_item_start': {
60122       var body = '';
60123
60124       while (this.next().type !== 'list_item_end') {
60125         body += this.tok();
60126       }
60127
60128       return this.renderer.listitem(body);
60129     }
60130     case 'html': {
60131       var html = !this.token.pre && !this.options.pedantic
60132         ? this.inline.output(this.token.text)
60133         : this.token.text;
60134       return this.renderer.html(html);
60135     }
60136     case 'paragraph': {
60137       return this.renderer.paragraph(this.inline.output(this.token.text));
60138     }
60139     case 'text': {
60140       return this.renderer.paragraph(this.parseText());
60141     }
60142   }
60143 };
60144
60145 /**
60146  * Helpers
60147  */
60148
60149 function escape(html, encode) {
60150   return html
60151     .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
60152     .replace(/</g, '&lt;')
60153     .replace(/>/g, '&gt;')
60154     .replace(/"/g, '&quot;')
60155     .replace(/'/g, '&#39;');
60156 }
60157
60158 function unescape(html) {
60159         // explicitly match decimal, hex, and named HTML entities 
60160   return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
60161     n = n.toLowerCase();
60162     if (n === 'colon') return ':';
60163     if (n.charAt(0) === '#') {
60164       return n.charAt(1) === 'x'
60165         ? String.fromCharCode(parseInt(n.substring(2), 16))
60166         : String.fromCharCode(+n.substring(1));
60167     }
60168     return '';
60169   });
60170 }
60171
60172 function replace(regex, opt) {
60173   regex = regex.source;
60174   opt = opt || '';
60175   return function self(name, val) {
60176     if (!name) return new RegExp(regex, opt);
60177     val = val.source || val;
60178     val = val.replace(/(^|[^\[])\^/g, '$1');
60179     regex = regex.replace(name, val);
60180     return self;
60181   };
60182 }
60183
60184 function noop() {}
60185 noop.exec = noop;
60186
60187 function merge(obj) {
60188   var i = 1
60189     , target
60190     , key;
60191
60192   for (; i < arguments.length; i++) {
60193     target = arguments[i];
60194     for (key in target) {
60195       if (Object.prototype.hasOwnProperty.call(target, key)) {
60196         obj[key] = target[key];
60197       }
60198     }
60199   }
60200
60201   return obj;
60202 }
60203
60204
60205 /**
60206  * Marked
60207  */
60208
60209 function marked(src, opt, callback) {
60210   if (callback || typeof opt === 'function') {
60211     if (!callback) {
60212       callback = opt;
60213       opt = null;
60214     }
60215
60216     opt = merge({}, marked.defaults, opt || {});
60217
60218     var highlight = opt.highlight
60219       , tokens
60220       , pending
60221       , i = 0;
60222
60223     try {
60224       tokens = Lexer.lex(src, opt);
60225     } catch (e) {
60226       return callback(e);
60227     }
60228
60229     pending = tokens.length;
60230
60231     var done = function(err) {
60232       if (err) {
60233         opt.highlight = highlight;
60234         return callback(err);
60235       }
60236
60237       var out;
60238
60239       try {
60240         out = Parser.parse(tokens, opt);
60241       } catch (e) {
60242         err = e;
60243       }
60244
60245       opt.highlight = highlight;
60246
60247       return err
60248         ? callback(err)
60249         : callback(null, out);
60250     };
60251
60252     if (!highlight || highlight.length < 3) {
60253       return done();
60254     }
60255
60256     delete opt.highlight;
60257
60258     if (!pending) return done();
60259
60260     for (; i < tokens.length; i++) {
60261       (function(token) {
60262         if (token.type !== 'code') {
60263           return --pending || done();
60264         }
60265         return highlight(token.text, token.lang, function(err, code) {
60266           if (err) return done(err);
60267           if (code == null || code === token.text) {
60268             return --pending || done();
60269           }
60270           token.text = code;
60271           token.escaped = true;
60272           --pending || done();
60273         });
60274       })(tokens[i]);
60275     }
60276
60277     return;
60278   }
60279   try {
60280     if (opt) opt = merge({}, marked.defaults, opt);
60281     return Parser.parse(Lexer.lex(src, opt), opt);
60282   } catch (e) {
60283     e.message += '\nPlease report this to https://github.com/chjj/marked.';
60284     if ((opt || marked.defaults).silent) {
60285       return '<p>An error occured:</p><pre>'
60286         + escape(e.message + '', true)
60287         + '</pre>';
60288     }
60289     throw e;
60290   }
60291 }
60292
60293 /**
60294  * Options
60295  */
60296
60297 marked.options =
60298 marked.setOptions = function(opt) {
60299   merge(marked.defaults, opt);
60300   return marked;
60301 };
60302
60303 marked.defaults = {
60304   gfm: true,
60305   tables: true,
60306   breaks: false,
60307   pedantic: false,
60308   sanitize: false,
60309   sanitizer: null,
60310   mangle: true,
60311   smartLists: false,
60312   silent: false,
60313   highlight: null,
60314   langPrefix: 'lang-',
60315   smartypants: false,
60316   headerPrefix: '',
60317   renderer: new Renderer,
60318   xhtml: false
60319 };
60320
60321 /**
60322  * Expose
60323  */
60324
60325 marked.Parser = Parser;
60326 marked.parser = Parser.parse;
60327
60328 marked.Renderer = Renderer;
60329
60330 marked.Lexer = Lexer;
60331 marked.lexer = Lexer.lex;
60332
60333 marked.InlineLexer = InlineLexer;
60334 marked.inlineLexer = InlineLexer.output;
60335
60336 marked.parse = marked;
60337
60338 {
60339   module.exports = marked;
60340 }
60341
60342 }).call(function() {
60343   return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
60344 }());
60345 });
60346
60347 function pointBox(loc, context) {
60348     var rect = context.surfaceRect();
60349     var point = context.curtainProjection(loc);
60350     return {
60351         left: point[0] + rect.left - 40,
60352         top: point[1] + rect.top - 60,
60353         width: 80,
60354         height: 90
60355     };
60356 }
60357
60358
60359 function pad$1(locOrBox, padding, context) {
60360     var box;
60361     if (locOrBox instanceof Array) {
60362         var rect = context.surfaceRect();
60363         var point = context.curtainProjection(locOrBox);
60364         box = {
60365             left: point[0] + rect.left,
60366             top: point[1] + rect.top
60367         };
60368     } else {
60369         box = locOrBox;
60370     }
60371
60372     return {
60373         left: box.left - padding,
60374         top: box.top - padding,
60375         width: (box.width || 0) + 2 * padding,
60376         height: (box.width || 0) + 2 * padding
60377     };
60378 }
60379
60380
60381 function icon(name, svgklass) {
60382     return '<svg class="icon ' + (svgklass || '') + '">' +
60383          '<use xlink:href="' + name + '"></use></svg>';
60384 }
60385
60386
60387 function slugify(text$$1) {
60388     return text$$1.toString().toLowerCase()
60389         .replace(/\s+/g, '-')           // Replace spaces with -
60390         .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
60391         .replace(/\-\-+/g, '-')         // Replace multiple - with single -
60392         .replace(/^-+/, '')             // Trim - from start of text
60393         .replace(/-+$/, '');            // Trim - from end of text
60394 }
60395
60396
60397 // console warning for missing walkthrough names
60398 var missingStrings = {};
60399 function checkKey(key, text$$1) {
60400     if (t(key, { default: undefined}) === undefined) {
60401         if (missingStrings.hasOwnProperty(key)) return;  // warn once
60402         missingStrings[key] = text$$1;
60403         var missing = key + ': ' + text$$1;
60404         if (typeof console !== 'undefined') console.log(missing); // eslint-disable-line
60405     }
60406 }
60407
60408
60409 function localize(obj) {
60410     var key;
60411
60412     // Assign name if entity has one..
60413     var name = obj.tags && obj.tags.name;
60414     if (name) {
60415         key = 'intro.graph.name.' + slugify(name);
60416         obj.tags.name = t(key, { default: name });
60417         checkKey(key, name);
60418     }
60419
60420     // Assign street name if entity has one..
60421     var street = obj.tags && obj.tags['addr:street'];
60422     if (street) {
60423         key = 'intro.graph.name.' + slugify(street);
60424         obj.tags['addr:street'] = t(key, { default: street });
60425         checkKey(key, street);
60426
60427         // Add address details common across walkthrough..
60428         var addrTags = [
60429             'block_number', 'city', 'county', 'district', 'hamlet', 'neighbourhood',
60430             'postcode', 'province', 'quarter', 'state', 'subdistrict', 'suburb'
60431         ];
60432         addrTags.forEach(function(k) {
60433             var key = 'intro.graph.' + k,
60434                 tag = 'addr:' + k,
60435                 val = obj.tags && obj.tags[tag],
60436                 str = t(key, { default: val });
60437
60438             if (str) {
60439                 if (str.match(/^<.*>$/) !== null) {
60440                     delete obj.tags[tag];
60441                 } else {
60442                     obj.tags[tag] = str;
60443                 }
60444             }
60445         });
60446     }
60447
60448     return obj;
60449 }
60450
60451
60452 // Used to detect squareness.. some duplicataion of code from actionOrthogonalize.
60453 function isMostlySquare(points) {
60454     // note: uses 15 here instead of the 12 from actionOrthogonalize because
60455     // actionOrthogonalize can actually straighten some larger angles as it iterates
60456     var threshold$$1 = 15, // degrees within right or straight
60457         lowerBound = Math.cos((90 - threshold$$1) * Math.PI / 180),  // near right
60458         upperBound = Math.cos(threshold$$1 * Math.PI / 180),         // near straight
60459         mag;
60460
60461     for (var i = 0; i < points.length; i++) {
60462         mag = Math.abs(normalizedDotProduct(i, points));
60463         if (mag > lowerBound && mag < upperBound) {
60464             return false;
60465         }
60466     }
60467
60468     return true;
60469
60470
60471     function normalizedDotProduct(i, points) {
60472         var a = points[(i - 1 + points.length) % points.length],
60473             b = points[i],
60474             c = points[(i + 1) % points.length],
60475             p = subtractPoints(a, b),
60476             q = subtractPoints(c, b);
60477
60478         p = normalizePoint(p);
60479         q = normalizePoint(q);
60480
60481         return p[0] * q[0] + p[1] * q[1];
60482
60483
60484         function subtractPoints(a, b) {
60485             return [a[0] - b[0], a[1] - b[1]];
60486         }
60487
60488         function normalizePoint(point) {
60489             var vector = [0, 0];
60490             var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
60491             if (length !== 0) {
60492                 vector[0] = point[0] / length;
60493                 vector[1] = point[1] / length;
60494             }
60495             return vector;
60496         }
60497     }
60498 }
60499
60500
60501 function selectMenuItem(operation) {
60502     var selector$$1 = '.edit-menu .edit-menu-item-' + operation +
60503         ', .radial-menu .radial-menu-item-' + operation;
60504     return select(selector$$1);
60505 }
60506
60507
60508 function transitionTime(point1, point2) {
60509     var distance$$1 = geoSphericalDistance(point1, point2);
60510     if (distance$$1 === 0)
60511         return 0;
60512     else if (distance$$1 < 80)
60513         return 500;
60514     else
60515         return 1000;
60516 }
60517
60518 var dataIntroGraph = {"n1":{"id":"n1","loc":[-85.631039,41.948829]},"n10":{"id":"n10","loc":[-85.634733,41.941588]},"n100":{"id":"n100","loc":[-85.637395,41.942252]},"n1000":{"id":"n1000","loc":[-85.632699,41.944763]},"n1001":{"id":"n1001","loc":[-85.632685,41.944763]},"n1002":{"id":"n1002","loc":[-85.632673,41.944755]},"n1003":{"id":"n1003","loc":[-85.632595,41.944682]},"n1004":{"id":"n1004","loc":[-85.632576,41.944673]},"n1005":{"id":"n1005","loc":[-85.632551,41.944667]},"n1006":{"id":"n1006","loc":[-85.63253,41.944667]},"n1007":{"id":"n1007","loc":[-85.632502,41.944669]},"n1008":{"id":"n1008","loc":[-85.632483,41.944677]},"n1009":{"id":"n1009","loc":[-85.632383,41.944731]},"n101":{"id":"n101","loc":[-85.637357,41.942252]},"n1010":{"id":"n1010","loc":[-85.63349,41.944976],"tags":{"addr:city":"Three Rivers","addr:housenumber":"31","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Sherwin-Williams","shop":"paint"}},"n1011":{"id":"n1011","loc":[-85.633548,41.945034],"tags":{"addr:city":"Three Rivers","addr:housenumber":"33","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Unique Jewelry","shop":"jewelry"}},"n1012":{"id":"n1012","loc":[-85.633683,41.945129],"tags":{"addr:city":"Three Rivers","addr:housenumber":"37","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"World Fare","shop":"gift"}},"n1013":{"id":"n1013","loc":[-85.634563,41.945469],"tags":{"addr:city":"Three Rivers","addr:housenumber":"62","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Golden Finch Framing","shop":"frame"}},"n1014":{"id":"n1014","loc":[-85.634469,41.945379],"tags":{"addr:city":"Three Rivers","addr:housenumber":"58","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Dollar Tree","shop":"second_hand"}},"n1015":{"id":"n1015","loc":[-85.634227,41.945159],"tags":{"addr:city":"Three Rivers","addr:housenumber":"48","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"theatre","name":"Riviera Theatre"}},"n1016":{"id":"n1016","loc":[-85.634057,41.945012],"tags":{"addr:city":"Three Rivers","addr:housenumber":"42","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"River City Appliance","shop":"appliance"}},"n1017":{"id":"n1017","loc":[-85.633879,41.945325],"tags":{"addr:city":"Three Rivers","addr:housenumber":"45","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Paparazzi Tattoo","shop":"tattoo"}},"n1018":{"id":"n1018","loc":[-85.634914,41.945839],"tags":{"addr:city":"Three Rivers","addr:housenumber":"88","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"bank","name":"Southern Michigan Bank"}},"n1019":{"id":"n1019","loc":[-85.634514,41.946176]},"n102":{"id":"n102","loc":[-85.637357,41.942216]},"n1020":{"id":"n1020","loc":[-85.634087,41.946178]},"n1021":{"id":"n1021","loc":[-85.634357,41.945805]},"n1022":{"id":"n1022","loc":[-85.634389,41.945788]},"n1023":{"id":"n1023","loc":[-85.634491,41.94581]},"n1024":{"id":"n1024","loc":[-85.634513,41.945853]},"n1025":{"id":"n1025","loc":[-85.634506,41.94583]},"n1026":{"id":"n1026","loc":[-85.634762,41.946056],"tags":{"crossing":"zebra","highway":"crossing"}},"n1027":{"id":"n1027","loc":[-85.634767,41.946172]},"n1028":{"id":"n1028","loc":[-85.634622,41.946175],"tags":{"crossing":"zebra","highway":"crossing"}},"n1029":{"id":"n1029","loc":[-85.640655,41.942057]},"n103":{"id":"n103","loc":[-85.637386,41.942054]},"n1030":{"id":"n1030","loc":[-85.640947,41.942057]},"n1031":{"id":"n1031","loc":[-85.640957,41.942593]},"n1032":{"id":"n1032","loc":[-85.630953,41.960873]},"n1033":{"id":"n1033","loc":[-85.632174,41.960679]},"n1034":{"id":"n1034","loc":[-85.638785,41.943066]},"n1035":{"id":"n1035","loc":[-85.638853,41.943065]},"n1036":{"id":"n1036","loc":[-85.638855,41.943183]},"n1037":{"id":"n1037","loc":[-85.638552,41.943189]},"n1038":{"id":"n1038","loc":[-85.63855,41.943149]},"n1039":{"id":"n1039","loc":[-85.638638,41.943068]},"n104":{"id":"n104","loc":[-85.637387,41.942125]},"n1040":{"id":"n1040","loc":[-85.638638,41.943078]},"n1041":{"id":"n1041","loc":[-85.638813,41.943163]},"n1042":{"id":"n1042","loc":[-85.638684,41.943165]},"n1043":{"id":"n1043","loc":[-85.638682,41.943105]},"n1044":{"id":"n1044","loc":[-85.638706,41.943105]},"n1045":{"id":"n1045","loc":[-85.638707,41.943117]},"n1046":{"id":"n1046","loc":[-85.638812,41.943115]},"n1047":{"id":"n1047","loc":[-85.638769,41.943407]},"n1048":{"id":"n1048","loc":[-85.638549,41.943407]},"n1049":{"id":"n1049","loc":[-85.638567,41.943555]},"n105":{"id":"n105","loc":[-85.637319,41.942125]},"n1050":{"id":"n1050","loc":[-85.638426,41.943554]},"n1051":{"id":"n1051","loc":[-85.638427,41.94346]},"n1052":{"id":"n1052","loc":[-85.638568,41.943461]},"n1053":{"id":"n1053","loc":[-85.639264,41.943415]},"n1054":{"id":"n1054","loc":[-85.639082,41.943417]},"n1055":{"id":"n1055","loc":[-85.63908,41.943331]},"n1056":{"id":"n1056","loc":[-85.639136,41.94333]},"n1057":{"id":"n1057","loc":[-85.639158,41.943312]},"n1058":{"id":"n1058","loc":[-85.639188,41.943313]},"n1059":{"id":"n1059","loc":[-85.639211,41.943331]},"n106":{"id":"n106","loc":[-85.637319,41.942137]},"n1060":{"id":"n1060","loc":[-85.639262,41.943331]},"n1061":{"id":"n1061","loc":[-85.638986,41.943515]},"n1062":{"id":"n1062","loc":[-85.63888,41.943521]},"n1063":{"id":"n1063","loc":[-85.638871,41.943436]},"n1064":{"id":"n1064","loc":[-85.638958,41.943431]},"n1065":{"id":"n1065","loc":[-85.638979,41.943443]},"n1066":{"id":"n1066","loc":[-85.63926,41.943703]},"n1067":{"id":"n1067","loc":[-85.639152,41.943704]},"n1068":{"id":"n1068","loc":[-85.639152,41.943691]},"n1069":{"id":"n1069","loc":[-85.639063,41.943691]},"n107":{"id":"n107","loc":[-85.637259,41.942137]},"n1070":{"id":"n1070","loc":[-85.639062,41.943613]},"n1071":{"id":"n1071","loc":[-85.639259,41.943611]},"n1072":{"id":"n1072","loc":[-85.639117,41.943726]},"n1073":{"id":"n1073","loc":[-85.639118,41.943767]},"n1074":{"id":"n1074","loc":[-85.639051,41.943768]},"n1075":{"id":"n1075","loc":[-85.63905,41.943727]},"n1076":{"id":"n1076","loc":[-85.638627,41.943716]},"n1077":{"id":"n1077","loc":[-85.63863,41.943634]},"n1078":{"id":"n1078","loc":[-85.63844,41.943631]},"n1079":{"id":"n1079","loc":[-85.638437,41.943729]},"n108":{"id":"n108","loc":[-85.637259,41.942126]},"n1080":{"id":"n1080","loc":[-85.638533,41.94373]},"n1081":{"id":"n1081","loc":[-85.638534,41.943715]},"n1082":{"id":"n1082","loc":[-85.638678,41.943941]},"n1083":{"id":"n1083","loc":[-85.638522,41.943944]},"n1084":{"id":"n1084","loc":[-85.63852,41.943864]},"n1085":{"id":"n1085","loc":[-85.638676,41.943861]},"n1086":{"id":"n1086","loc":[-85.638663,41.944059]},"n1087":{"id":"n1087","loc":[-85.638513,41.944061]},"n1088":{"id":"n1088","loc":[-85.638511,41.943991]},"n1089":{"id":"n1089","loc":[-85.638661,41.943989]},"n109":{"id":"n109","loc":[-85.637193,41.942126]},"n1090":{"id":"n1090","loc":[-85.63865,41.944134]},"n1091":{"id":"n1091","loc":[-85.638429,41.944144]},"n1092":{"id":"n1092","loc":[-85.638426,41.944106]},"n1093":{"id":"n1093","loc":[-85.638476,41.944104]},"n1094":{"id":"n1094","loc":[-85.638475,41.94409]},"n1095":{"id":"n1095","loc":[-85.638594,41.944084]},"n1096":{"id":"n1096","loc":[-85.638595,41.944101]},"n1097":{"id":"n1097","loc":[-85.638647,41.944099]},"n1098":{"id":"n1098","loc":[-85.63829,41.944154]},"n1099":{"id":"n1099","loc":[-85.638558,41.944155]},"n11":{"id":"n11","loc":[-85.634602,41.941523]},"n110":{"id":"n110","loc":[-85.637192,41.942053]},"n1100":{"id":"n1100","loc":[-85.638558,41.944338]},"n1101":{"id":"n1101","loc":[-85.638851,41.944408]},"n1102":{"id":"n1102","loc":[-85.637771,41.943989]},"n1103":{"id":"n1103","loc":[-85.639345,41.943964]},"n1104":{"id":"n1104","loc":[-85.638515,41.94397]},"n1105":{"id":"n1105","loc":[-85.639256,41.943928]},"n1106":{"id":"n1106","loc":[-85.639157,41.943929]},"n1107":{"id":"n1107","loc":[-85.639156,41.9439]},"n1108":{"id":"n1108","loc":[-85.639118,41.9439]},"n1109":{"id":"n1109","loc":[-85.639116,41.94382]},"n111":{"id":"n111","loc":[-85.637248,41.942053]},"n1110":{"id":"n1110","loc":[-85.639202,41.943819]},"n1111":{"id":"n1111","loc":[-85.639202,41.943837]},"n1112":{"id":"n1112","loc":[-85.639293,41.943836]},"n1113":{"id":"n1113","loc":[-85.639295,41.943898]},"n1114":{"id":"n1114","loc":[-85.639255,41.943898]},"n1115":{"id":"n1115","loc":[-85.639296,41.944083]},"n1116":{"id":"n1116","loc":[-85.639144,41.944084]},"n1117":{"id":"n1117","loc":[-85.639143,41.944026]},"n1118":{"id":"n1118","loc":[-85.639162,41.944026]},"n1119":{"id":"n1119","loc":[-85.639162,41.944]},"n112":{"id":"n112","loc":[-85.637248,41.942042]},"n1120":{"id":"n1120","loc":[-85.639295,41.943999]},"n1121":{"id":"n1121","loc":[-85.639131,41.944139]},"n1122":{"id":"n1122","loc":[-85.63901,41.94414]},"n1123":{"id":"n1123","loc":[-85.63901,41.944076]},"n1124":{"id":"n1124","loc":[-85.63913,41.944075]},"n1125":{"id":"n1125","loc":[-85.639092,41.944155]},"n1126":{"id":"n1126","loc":[-85.639093,41.944308]},"n1127":{"id":"n1127","loc":[-85.639225,41.944308]},"n1128":{"id":"n1128","loc":[-85.639225,41.94429]},"n1129":{"id":"n1129","loc":[-85.639253,41.944289]},"n113":{"id":"n113","loc":[-85.637338,41.942041]},"n1130":{"id":"n1130","loc":[-85.639253,41.944269]},"n1131":{"id":"n1131","loc":[-85.639243,41.944269]},"n1132":{"id":"n1132","loc":[-85.639243,41.944229]},"n1133":{"id":"n1133","loc":[-85.639224,41.944229]},"n1134":{"id":"n1134","loc":[-85.639224,41.944196]},"n1135":{"id":"n1135","loc":[-85.639195,41.944196]},"n1136":{"id":"n1136","loc":[-85.639195,41.944155]},"n1137":{"id":"n1137","loc":[-85.639072,41.944154]},"n1138":{"id":"n1138","loc":[-85.638865,41.944154]},"n1139":{"id":"n1139","loc":[-85.638863,41.943967]},"n114":{"id":"n114","loc":[-85.637338,41.942055]},"n1140":{"id":"n1140","loc":[-85.6386,41.942698]},"n1141":{"id":"n1141","loc":[-85.639348,41.942698]},"n1142":{"id":"n1142","loc":[-85.639377,41.944984]},"n1143":{"id":"n1143","loc":[-85.63937,41.945013]},"n1144":{"id":"n1144","loc":[-85.639357,41.945033]},"n1145":{"id":"n1145","loc":[-85.639353,41.945053]},"n1146":{"id":"n1146","loc":[-85.639352,41.945084]},"n1147":{"id":"n1147","loc":[-85.638278,41.945516]},"n1148":{"id":"n1148","loc":[-85.637505,41.945801]},"n1149":{"id":"n1149","loc":[-85.637327,41.945857]},"n115":{"id":"n115","loc":[-85.637583,41.941943]},"n1150":{"id":"n1150","loc":[-85.637168,41.945899]},"n1151":{"id":"n1151","loc":[-85.637017,41.94593]},"n1152":{"id":"n1152","loc":[-85.637185,41.945938]},"n1153":{"id":"n1153","loc":[-85.63682,41.945963]},"n1154":{"id":"n1154","loc":[-85.636639,41.945984]},"n1155":{"id":"n1155","loc":[-85.636439,41.945999]},"n1156":{"id":"n1156","loc":[-85.635801,41.945999]},"n1157":{"id":"n1157","loc":[-85.635769,41.945908]},"n1158":{"id":"n1158","loc":[-85.635953,41.946154]},"n1159":{"id":"n1159","loc":[-85.635472,41.94598]},"n116":{"id":"n116","loc":[-85.637584,41.941983]},"n1160":{"id":"n1160","loc":[-85.635409,41.945981]},"n1161":{"id":"n1161","loc":[-85.635583,41.945987]},"n1162":{"id":"n1162","loc":[-85.636452,41.945805]},"n1163":{"id":"n1163","loc":[-85.636425,41.94582]},"n1164":{"id":"n1164","loc":[-85.636396,41.945817]},"n1165":{"id":"n1165","loc":[-85.636368,41.945797]},"n1166":{"id":"n1166","loc":[-85.636346,41.945767]},"n1167":{"id":"n1167","loc":[-85.636307,41.945745]},"n1168":{"id":"n1168","loc":[-85.636194,41.94565]},"n1169":{"id":"n1169","loc":[-85.636121,41.945579]},"n117":{"id":"n117","loc":[-85.63751,41.941983]},"n1170":{"id":"n1170","loc":[-85.635995,41.945432]},"n1171":{"id":"n1171","loc":[-85.637564,41.943538]},"n1172":{"id":"n1172","loc":[-85.63756,41.943505]},"n1173":{"id":"n1173","loc":[-85.637435,41.943489]},"n1174":{"id":"n1174","loc":[-85.637093,41.943556]},"n1175":{"id":"n1175","loc":[-85.634836,41.941574]},"n1176":{"id":"n1176","loc":[-85.634692,41.9415]},"n1177":{"id":"n1177","loc":[-85.634261,41.941337]},"n1178":{"id":"n1178","loc":[-85.634208,41.940962]},"n1179":{"id":"n1179","loc":[-85.635247,41.940968]},"n118":{"id":"n118","loc":[-85.637509,41.941944]},"n1180":{"id":"n1180","loc":[-85.63514,41.941205]},"n1181":{"id":"n1181","loc":[-85.634858,41.941511]},"n1182":{"id":"n1182","loc":[-85.630725,41.943465]},"n1183":{"id":"n1183","loc":[-85.632591,41.942826]},"n1184":{"id":"n1184","loc":[-85.634487,41.941928]},"n1185":{"id":"n1185","loc":[-85.634499,41.942056]},"n1186":{"id":"n1186","loc":[-85.63433,41.943102]},"n1187":{"id":"n1187","loc":[-85.634158,41.943151]},"n1188":{"id":"n1188","loc":[-85.634107,41.94305]},"n1189":{"id":"n1189","loc":[-85.634279,41.943002]},"n119":{"id":"n119","loc":[-85.637724,41.941973]},"n1190":{"id":"n1190","loc":[-85.634362,41.943762]},"n1191":{"id":"n1191","loc":[-85.634331,41.943731]},"n1192":{"id":"n1192","loc":[-85.634396,41.943695]},"n1193":{"id":"n1193","loc":[-85.634426,41.943726]},"n1194":{"id":"n1194","loc":[-85.621569,41.956021]},"n1195":{"id":"n1195","loc":[-85.621574,41.956164]},"n1196":{"id":"n1196","loc":[-85.621489,41.956165]},"n1197":{"id":"n1197","loc":[-85.621488,41.956136]},"n1198":{"id":"n1198","loc":[-85.621372,41.956139]},"n1199":{"id":"n1199","loc":[-85.621369,41.956049]},"n12":{"id":"n12","loc":[-85.63359,41.941093]},"n120":{"id":"n120","loc":[-85.637633,41.941973]},"n1200":{"id":"n1200","loc":[-85.621493,41.956047]},"n1201":{"id":"n1201","loc":[-85.621492,41.956022]},"n1202":{"id":"n1202","loc":[-85.619744,41.953192]},"n1203":{"id":"n1203","loc":[-85.619059,41.953902]},"n1204":{"id":"n1204","loc":[-85.623984,41.95469]},"n1205":{"id":"n1205","loc":[-85.630159,41.958208]},"n1206":{"id":"n1206","loc":[-85.63002,41.958208]},"n1207":{"id":"n1207","loc":[-85.630021,41.95814]},"n1208":{"id":"n1208","loc":[-85.63,41.95814]},"n1209":{"id":"n1209","loc":[-85.63,41.958043]},"n121":{"id":"n121","loc":[-85.637633,41.941853]},"n1210":{"id":"n1210","loc":[-85.630159,41.958043]},"n1211":{"id":"n1211","loc":[-85.630304,41.957566]},"n1212":{"id":"n1212","loc":[-85.630303,41.957684]},"n1213":{"id":"n1213","loc":[-85.630073,41.957683]},"n1214":{"id":"n1214","loc":[-85.630072,41.957721]},"n1215":{"id":"n1215","loc":[-85.629993,41.95772]},"n1216":{"id":"n1216","loc":[-85.629993,41.95768]},"n1217":{"id":"n1217","loc":[-85.629968,41.95768]},"n1218":{"id":"n1218","loc":[-85.629969,41.957588]},"n1219":{"id":"n1219","loc":[-85.630219,41.95759]},"n122":{"id":"n122","loc":[-85.637724,41.941853]},"n1220":{"id":"n1220","loc":[-85.630219,41.957566]},"n1221":{"id":"n1221","loc":[-85.630717,41.957744]},"n1222":{"id":"n1222","loc":[-85.630596,41.957745]},"n1223":{"id":"n1223","loc":[-85.630598,41.957553]},"n1224":{"id":"n1224","loc":[-85.630717,41.957555]},"n1225":{"id":"n1225","loc":[-85.630609,41.957745]},"n1226":{"id":"n1226","loc":[-85.63061,41.957789]},"n1227":{"id":"n1227","loc":[-85.630327,41.957791]},"n1228":{"id":"n1228","loc":[-85.630324,41.95752]},"n1229":{"id":"n1229","loc":[-85.630325,41.95756]},"n123":{"id":"n123","loc":[-85.637773,41.941988]},"n1230":{"id":"n1230","loc":[-85.63057,41.95756]},"n1231":{"id":"n1231","loc":[-85.63069,41.958016]},"n1232":{"id":"n1232","loc":[-85.630586,41.958017]},"n1233":{"id":"n1233","loc":[-85.630584,41.957956]},"n1234":{"id":"n1234","loc":[-85.630614,41.957956]},"n1235":{"id":"n1235","loc":[-85.630611,41.957835]},"n1236":{"id":"n1236","loc":[-85.630737,41.957833]},"n1237":{"id":"n1237","loc":[-85.630739,41.957921]},"n1238":{"id":"n1238","loc":[-85.630688,41.957922]},"n1239":{"id":"n1239","loc":[-85.630719,41.958291]},"n124":{"id":"n124","loc":[-85.637773,41.942046]},"n1240":{"id":"n1240","loc":[-85.630592,41.958291]},"n1241":{"id":"n1241","loc":[-85.630593,41.958108]},"n1242":{"id":"n1242","loc":[-85.630701,41.958109]},"n1243":{"id":"n1243","loc":[-85.6307,41.958173]},"n1244":{"id":"n1244","loc":[-85.630711,41.958173]},"n1245":{"id":"n1245","loc":[-85.630711,41.958233]},"n1246":{"id":"n1246","loc":[-85.630719,41.958233]},"n1247":{"id":"n1247","loc":[-85.630523,41.958329]},"n1248":{"id":"n1248","loc":[-85.630388,41.958329]},"n1249":{"id":"n1249","loc":[-85.630387,41.958262]},"n125":{"id":"n125","loc":[-85.637693,41.942047]},"n1250":{"id":"n1250","loc":[-85.630523,41.958261]},"n1251":{"id":"n1251","loc":[-85.63072,41.958636]},"n1252":{"id":"n1252","loc":[-85.630721,41.958709]},"n1253":{"id":"n1253","loc":[-85.630503,41.958712]},"n1254":{"id":"n1254","loc":[-85.630498,41.958511]},"n1255":{"id":"n1255","loc":[-85.630635,41.95851]},"n1256":{"id":"n1256","loc":[-85.630638,41.958636]},"n1257":{"id":"n1257","loc":[-85.630437,41.958822]},"n1258":{"id":"n1258","loc":[-85.630437,41.958849]},"n1259":{"id":"n1259","loc":[-85.630393,41.958849]},"n126":{"id":"n126","loc":[-85.637692,41.941988]},"n1260":{"id":"n1260","loc":[-85.630393,41.958822]},"n1261":{"id":"n1261","loc":[-85.630605,41.959102]},"n1262":{"id":"n1262","loc":[-85.63049,41.959104]},"n1263":{"id":"n1263","loc":[-85.630487,41.958996]},"n1264":{"id":"n1264","loc":[-85.630462,41.958996]},"n1265":{"id":"n1265","loc":[-85.63046,41.958922]},"n1266":{"id":"n1266","loc":[-85.630562,41.958921]},"n1267":{"id":"n1267","loc":[-85.630564,41.958992]},"n1268":{"id":"n1268","loc":[-85.630602,41.958992]},"n1269":{"id":"n1269","loc":[-85.630126,41.957096]},"n127":{"id":"n127","loc":[-85.637604,41.941994]},"n1270":{"id":"n1270","loc":[-85.630129,41.957283]},"n1271":{"id":"n1271","loc":[-85.629993,41.957284]},"n1272":{"id":"n1272","loc":[-85.629992,41.957216]},"n1273":{"id":"n1273","loc":[-85.630015,41.957215]},"n1274":{"id":"n1274","loc":[-85.630013,41.957097]},"n1275":{"id":"n1275","loc":[-85.630211,41.956592]},"n1276":{"id":"n1276","loc":[-85.630211,41.956676]},"n1277":{"id":"n1277","loc":[-85.630162,41.956676]},"n1278":{"id":"n1278","loc":[-85.630162,41.95676]},"n1279":{"id":"n1279","loc":[-85.630037,41.956761]},"n128":{"id":"n128","loc":[-85.637604,41.942057]},"n1280":{"id":"n1280","loc":[-85.630037,41.956592]},"n1281":{"id":"n1281","loc":[-85.630309,41.95653]},"n1282":{"id":"n1282","loc":[-85.630326,41.957065]},"n1283":{"id":"n1283","loc":[-85.630118,41.957065]},"n1284":{"id":"n1284","loc":[-85.630119,41.957096]},"n1285":{"id":"n1285","loc":[-85.63067,41.957307]},"n1286":{"id":"n1286","loc":[-85.630536,41.957308]},"n1287":{"id":"n1287","loc":[-85.630533,41.957111]},"n1288":{"id":"n1288","loc":[-85.630667,41.95711]},"n1289":{"id":"n1289","loc":[-85.630676,41.956808]},"n129":{"id":"n129","loc":[-85.63748,41.942057]},"n1290":{"id":"n1290","loc":[-85.630551,41.956808]},"n1291":{"id":"n1291","loc":[-85.630552,41.956982]},"n1292":{"id":"n1292","loc":[-85.63059,41.956982]},"n1293":{"id":"n1293","loc":[-85.63059,41.957001]},"n1294":{"id":"n1294","loc":[-85.630692,41.957001]},"n1295":{"id":"n1295","loc":[-85.630692,41.956936]},"n1296":{"id":"n1296","loc":[-85.630676,41.956936]},"n1297":{"id":"n1297","loc":[-85.630496,41.956889]},"n1298":{"id":"n1298","loc":[-85.630501,41.956947]},"n1299":{"id":"n1299","loc":[-85.630377,41.956953]},"n13":{"id":"n13","loc":[-85.633643,41.941143]},"n130":{"id":"n130","loc":[-85.63748,41.941994]},"n1300":{"id":"n1300","loc":[-85.630359,41.956938]},"n1301":{"id":"n1301","loc":[-85.630359,41.956912]},"n1302":{"id":"n1302","loc":[-85.63038,41.956894]},"n1303":{"id":"n1303","loc":[-85.630679,41.956747]},"n1304":{"id":"n1304","loc":[-85.630572,41.956748]},"n1305":{"id":"n1305","loc":[-85.63057,41.956668]},"n1306":{"id":"n1306","loc":[-85.630501,41.956669]},"n1307":{"id":"n1307","loc":[-85.630499,41.95659]},"n1308":{"id":"n1308","loc":[-85.630565,41.956589]},"n1309":{"id":"n1309","loc":[-85.630564,41.956541]},"n131":{"id":"n131","loc":[-85.637431,41.941832]},"n1310":{"id":"n1310","loc":[-85.630686,41.956539]},"n1311":{"id":"n1311","loc":[-85.630688,41.956631]},"n1312":{"id":"n1312","loc":[-85.630676,41.956631]},"n1313":{"id":"n1313","loc":[-85.630686,41.956487]},"n1314":{"id":"n1314","loc":[-85.63059,41.956487]},"n1315":{"id":"n1315","loc":[-85.63059,41.956396]},"n1316":{"id":"n1316","loc":[-85.630686,41.956396]},"n1317":{"id":"n1317","loc":[-85.630643,41.9563]},"n1318":{"id":"n1318","loc":[-85.630548,41.956301]},"n1319":{"id":"n1319","loc":[-85.630545,41.956217]},"n132":{"id":"n132","loc":[-85.637432,41.94189]},"n1320":{"id":"n1320","loc":[-85.630529,41.956214]},"n1321":{"id":"n1321","loc":[-85.630521,41.956202]},"n1322":{"id":"n1322","loc":[-85.63052,41.95618]},"n1323":{"id":"n1323","loc":[-85.630527,41.956169]},"n1324":{"id":"n1324","loc":[-85.630544,41.956163]},"n1325":{"id":"n1325","loc":[-85.630543,41.956094]},"n1326":{"id":"n1326","loc":[-85.630641,41.956093]},"n1327":{"id":"n1327","loc":[-85.630642,41.956134]},"n1328":{"id":"n1328","loc":[-85.630656,41.956134]},"n1329":{"id":"n1329","loc":[-85.630657,41.956252]},"n133":{"id":"n133","loc":[-85.637412,41.94189]},"n1330":{"id":"n1330","loc":[-85.630643,41.956252]},"n1331":{"id":"n1331","loc":[-85.630409,41.956044]},"n1332":{"id":"n1332","loc":[-85.630409,41.956075]},"n1333":{"id":"n1333","loc":[-85.630195,41.956078]},"n1334":{"id":"n1334","loc":[-85.630195,41.9561]},"n1335":{"id":"n1335","loc":[-85.630088,41.956101]},"n1336":{"id":"n1336","loc":[-85.630087,41.956048]},"n1337":{"id":"n1337","loc":[-85.630345,41.956114]},"n1338":{"id":"n1338","loc":[-85.630328,41.956113]},"n1339":{"id":"n1339","loc":[-85.63034,41.956189]},"n134":{"id":"n134","loc":[-85.637413,41.941938]},"n1340":{"id":"n1340","loc":[-85.630355,41.956185]},"n1341":{"id":"n1341","loc":[-85.630311,41.956117]},"n1342":{"id":"n1342","loc":[-85.630297,41.956125]},"n1343":{"id":"n1343","loc":[-85.630287,41.956136]},"n1344":{"id":"n1344","loc":[-85.630283,41.956149]},"n1345":{"id":"n1345","loc":[-85.630285,41.956162]},"n1346":{"id":"n1346","loc":[-85.630293,41.956174]},"n1347":{"id":"n1347","loc":[-85.630306,41.956183]},"n1348":{"id":"n1348","loc":[-85.630322,41.956188]},"n1349":{"id":"n1349","loc":[-85.630368,41.956179]},"n135":{"id":"n135","loc":[-85.637342,41.941939]},"n1350":{"id":"n1350","loc":[-85.630378,41.95617]},"n1351":{"id":"n1351","loc":[-85.630384,41.956159]},"n1352":{"id":"n1352","loc":[-85.630385,41.956147]},"n1353":{"id":"n1353","loc":[-85.630381,41.956136]},"n1354":{"id":"n1354","loc":[-85.630372,41.956126]},"n1355":{"id":"n1355","loc":[-85.63036,41.956118]},"n1356":{"id":"n1356","loc":[-85.630776,41.956041]},"n1357":{"id":"n1357","loc":[-85.630195,41.956036]},"n1358":{"id":"n1358","loc":[-85.630137,41.956037]},"n1359":{"id":"n1359","loc":[-85.630136,41.956006]},"n136":{"id":"n136","loc":[-85.637342,41.941914]},"n1360":{"id":"n1360","loc":[-85.630194,41.956005]},"n1361":{"id":"n1361","loc":[-85.629864,41.956039]},"n1362":{"id":"n1362","loc":[-85.629864,41.955862]},"n1363":{"id":"n1363","loc":[-85.629541,41.958291]},"n1364":{"id":"n1364","loc":[-85.629419,41.958292]},"n1365":{"id":"n1365","loc":[-85.629417,41.958168]},"n1366":{"id":"n1366","loc":[-85.629445,41.958168]},"n1367":{"id":"n1367","loc":[-85.629444,41.958109]},"n1368":{"id":"n1368","loc":[-85.629537,41.958108]},"n1369":{"id":"n1369","loc":[-85.629351,41.958136]},"n137":{"id":"n137","loc":[-85.637212,41.941916]},"n1370":{"id":"n1370","loc":[-85.629352,41.958202]},"n1371":{"id":"n1371","loc":[-85.629365,41.958202]},"n1372":{"id":"n1372","loc":[-85.629365,41.958223]},"n1373":{"id":"n1373","loc":[-85.629291,41.958224]},"n1374":{"id":"n1374","loc":[-85.62929,41.958137]},"n1375":{"id":"n1375","loc":[-85.629443,41.958073]},"n1376":{"id":"n1376","loc":[-85.629252,41.958075]},"n1377":{"id":"n1377","loc":[-85.629253,41.95827]},"n1378":{"id":"n1378","loc":[-85.629566,41.957585]},"n1379":{"id":"n1379","loc":[-85.629566,41.957692]},"n138":{"id":"n138","loc":[-85.637211,41.941835]},"n1380":{"id":"n1380","loc":[-85.629281,41.957693]},"n1381":{"id":"n1381","loc":[-85.62928,41.957585]},"n1382":{"id":"n1382","loc":[-85.629004,41.957599]},"n1383":{"id":"n1383","loc":[-85.629004,41.957682]},"n1384":{"id":"n1384","loc":[-85.628902,41.957682]},"n1385":{"id":"n1385","loc":[-85.628902,41.957723]},"n1386":{"id":"n1386","loc":[-85.628731,41.957724]},"n1387":{"id":"n1387","loc":[-85.628731,41.9576]},"n1388":{"id":"n1388","loc":[-85.62836,41.957679]},"n1389":{"id":"n1389","loc":[-85.628359,41.957759]},"n139":{"id":"n139","loc":[-85.637293,41.941834]},"n1390":{"id":"n1390","loc":[-85.628062,41.957757]},"n1391":{"id":"n1391","loc":[-85.628063,41.957657]},"n1392":{"id":"n1392","loc":[-85.628198,41.957657]},"n1393":{"id":"n1393","loc":[-85.628198,41.957678]},"n1394":{"id":"n1394","loc":[-85.627775,41.958095]},"n1395":{"id":"n1395","loc":[-85.627608,41.958095]},"n1396":{"id":"n1396","loc":[-85.627606,41.957829]},"n1397":{"id":"n1397","loc":[-85.627774,41.957829]},"n1398":{"id":"n1398","loc":[-85.626816,41.957636]},"n1399":{"id":"n1399","loc":[-85.626787,41.957681]},"n14":{"id":"n14","loc":[-85.633643,41.940122]},"n140":{"id":"n140","loc":[-85.637293,41.941823]},"n1400":{"id":"n1400","loc":[-85.626673,41.95764]},"n1401":{"id":"n1401","loc":[-85.626703,41.957594]},"n1402":{"id":"n1402","loc":[-85.62694,41.95752]},"n1403":{"id":"n1403","loc":[-85.62688,41.957611]},"n1404":{"id":"n1404","loc":[-85.626798,41.957582]},"n1405":{"id":"n1405","loc":[-85.626793,41.95759]},"n1406":{"id":"n1406","loc":[-85.626657,41.95754]},"n1407":{"id":"n1407","loc":[-85.626666,41.957526]},"n1408":{"id":"n1408","loc":[-85.626584,41.957497]},"n1409":{"id":"n1409","loc":[-85.626638,41.957415]},"n141":{"id":"n141","loc":[-85.637363,41.941822]},"n1410":{"id":"n1410","loc":[-85.626731,41.957449]},"n1411":{"id":"n1411","loc":[-85.626725,41.957457]},"n1412":{"id":"n1412","loc":[-85.626843,41.9575]},"n1413":{"id":"n1413","loc":[-85.626851,41.957487]},"n1414":{"id":"n1414","loc":[-85.626579,41.957521]},"n1415":{"id":"n1415","loc":[-85.626537,41.957587]},"n1416":{"id":"n1416","loc":[-85.626427,41.957551]},"n1417":{"id":"n1417","loc":[-85.626468,41.957483]},"n1418":{"id":"n1418","loc":[-85.626592,41.957639]},"n1419":{"id":"n1419","loc":[-85.626807,41.957713]},"n142":{"id":"n142","loc":[-85.637364,41.941833]},"n1420":{"id":"n1420","loc":[-85.627129,41.957401]},"n1421":{"id":"n1421","loc":[-85.627209,41.95742]},"n1422":{"id":"n1422","loc":[-85.627302,41.957435]},"n1423":{"id":"n1423","loc":[-85.629566,41.957048]},"n1424":{"id":"n1424","loc":[-85.629568,41.957215]},"n1425":{"id":"n1425","loc":[-85.629383,41.957216]},"n1426":{"id":"n1426","loc":[-85.629384,41.95727]},"n1427":{"id":"n1427","loc":[-85.629231,41.957271]},"n1428":{"id":"n1428","loc":[-85.62923,41.957198]},"n1429":{"id":"n1429","loc":[-85.629322,41.957198]},"n143":{"id":"n143","loc":[-85.637559,41.942448]},"n1430":{"id":"n1430","loc":[-85.629321,41.957108]},"n1431":{"id":"n1431","loc":[-85.629441,41.957108]},"n1432":{"id":"n1432","loc":[-85.62944,41.957049]},"n1433":{"id":"n1433","loc":[-85.629337,41.957018]},"n1434":{"id":"n1434","loc":[-85.629366,41.957028]},"n1435":{"id":"n1435","loc":[-85.629375,41.957044]},"n1436":{"id":"n1436","loc":[-85.629354,41.957071]},"n1437":{"id":"n1437","loc":[-85.629317,41.957071]},"n1438":{"id":"n1438","loc":[-85.62929,41.957074]},"n1439":{"id":"n1439","loc":[-85.62927,41.957084]},"n144":{"id":"n144","loc":[-85.637036,41.942454]},"n1440":{"id":"n1440","loc":[-85.629232,41.957081]},"n1441":{"id":"n1441","loc":[-85.629222,41.957057]},"n1442":{"id":"n1442","loc":[-85.629259,41.957025]},"n1443":{"id":"n1443","loc":[-85.629293,41.957017]},"n1444":{"id":"n1444","loc":[-85.629251,41.957085]},"n1445":{"id":"n1445","loc":[-85.629235,41.957041]},"n1446":{"id":"n1446","loc":[-85.62937,41.95706]},"n1447":{"id":"n1447","loc":[-85.629531,41.956909]},"n1448":{"id":"n1448","loc":[-85.629408,41.956909]},"n1449":{"id":"n1449","loc":[-85.629402,41.956681]},"n145":{"id":"n145","loc":[-85.636692,41.942828]},"n1450":{"id":"n1450","loc":[-85.62953,41.956681]},"n1451":{"id":"n1451","loc":[-85.629402,41.956728]},"n1452":{"id":"n1452","loc":[-85.629408,41.956845]},"n1453":{"id":"n1453","loc":[-85.629385,41.956845]},"n1454":{"id":"n1454","loc":[-85.629384,41.956728]},"n1455":{"id":"n1455","loc":[-85.629063,41.956973]},"n1456":{"id":"n1456","loc":[-85.629064,41.957009]},"n1457":{"id":"n1457","loc":[-85.62902,41.957009]},"n1458":{"id":"n1458","loc":[-85.629019,41.956973]},"n1459":{"id":"n1459","loc":[-85.629136,41.956633]},"n146":{"id":"n146","loc":[-85.635929,41.942826]},"n1460":{"id":"n1460","loc":[-85.629084,41.956632]},"n1461":{"id":"n1461","loc":[-85.629084,41.956605]},"n1462":{"id":"n1462","loc":[-85.629136,41.956605]},"n1463":{"id":"n1463","loc":[-85.629153,41.956657]},"n1464":{"id":"n1464","loc":[-85.627914,41.956661]},"n1465":{"id":"n1465","loc":[-85.630096,41.956101]},"n1466":{"id":"n1466","loc":[-85.630097,41.95612]},"n1467":{"id":"n1467","loc":[-85.630011,41.956121]},"n1468":{"id":"n1468","loc":[-85.630015,41.956374]},"n1469":{"id":"n1469","loc":[-85.629148,41.95626]},"n147":{"id":"n147","loc":[-85.636433,41.942828]},"n1470":{"id":"n1470","loc":[-85.629527,41.956591]},"n1471":{"id":"n1471","loc":[-85.629405,41.956591]},"n1472":{"id":"n1472","loc":[-85.629405,41.956459]},"n1473":{"id":"n1473","loc":[-85.629369,41.956459]},"n1474":{"id":"n1474","loc":[-85.629369,41.956424]},"n1475":{"id":"n1475","loc":[-85.629413,41.956424]},"n1476":{"id":"n1476","loc":[-85.629414,41.956326]},"n1477":{"id":"n1477","loc":[-85.629522,41.956326]},"n1478":{"id":"n1478","loc":[-85.629522,41.956487]},"n1479":{"id":"n1479","loc":[-85.629527,41.956487]},"n148":{"id":"n148","loc":[-85.636435,41.942864],"tags":{"entrance":"yes"}},"n1480":{"id":"n1480","loc":[-85.629414,41.95634]},"n1481":{"id":"n1481","loc":[-85.629149,41.956338]},"n1482":{"id":"n1482","loc":[-85.62931,41.956531]},"n1483":{"id":"n1483","loc":[-85.629291,41.95655]},"n1484":{"id":"n1484","loc":[-85.629255,41.95655]},"n1485":{"id":"n1485","loc":[-85.629236,41.956533]},"n1486":{"id":"n1486","loc":[-85.629237,41.956461]},"n1487":{"id":"n1487","loc":[-85.629257,41.956445]},"n1488":{"id":"n1488","loc":[-85.629257,41.956428]},"n1489":{"id":"n1489","loc":[-85.629287,41.956428]},"n149":{"id":"n149","loc":[-85.637235,41.942622]},"n1490":{"id":"n1490","loc":[-85.629287,41.956445]},"n1491":{"id":"n1491","loc":[-85.62931,41.95646]},"n1492":{"id":"n1492","loc":[-85.629049,41.956425]},"n1493":{"id":"n1493","loc":[-85.628907,41.956427]},"n1494":{"id":"n1494","loc":[-85.628907,41.956455]},"n1495":{"id":"n1495","loc":[-85.628841,41.956455]},"n1496":{"id":"n1496","loc":[-85.62884,41.956424]},"n1497":{"id":"n1497","loc":[-85.628764,41.956425]},"n1498":{"id":"n1498","loc":[-85.628762,41.956323]},"n1499":{"id":"n1499","loc":[-85.628808,41.956323]},"n15":{"id":"n15","loc":[-85.633477,41.940187]},"n150":{"id":"n150","loc":[-85.637247,41.943116]},"n1500":{"id":"n1500","loc":[-85.628808,41.956314]},"n1501":{"id":"n1501","loc":[-85.628911,41.956313]},"n1502":{"id":"n1502","loc":[-85.628911,41.956322]},"n1503":{"id":"n1503","loc":[-85.62896,41.956322]},"n1504":{"id":"n1504","loc":[-85.62896,41.956348]},"n1505":{"id":"n1505","loc":[-85.629047,41.956347]},"n1506":{"id":"n1506","loc":[-85.628893,41.957263]},"n1507":{"id":"n1507","loc":[-85.628788,41.957264]},"n1508":{"id":"n1508","loc":[-85.628786,41.95711]},"n1509":{"id":"n1509","loc":[-85.628894,41.957109]},"n151":{"id":"n151","loc":[-85.637564,41.943116]},"n1510":{"id":"n1510","loc":[-85.628893,41.957075]},"n1511":{"id":"n1511","loc":[-85.628965,41.957075]},"n1512":{"id":"n1512","loc":[-85.628965,41.957111]},"n1513":{"id":"n1513","loc":[-85.629035,41.95711]},"n1514":{"id":"n1514","loc":[-85.629036,41.957209]},"n1515":{"id":"n1515","loc":[-85.628893,41.95721]},"n1516":{"id":"n1516","loc":[-85.631348,41.95773]},"n1517":{"id":"n1517","loc":[-85.631101,41.957732]},"n1518":{"id":"n1518","loc":[-85.631099,41.957558]},"n1519":{"id":"n1519","loc":[-85.63123,41.957557]},"n152":{"id":"n152","loc":[-85.637552,41.942619]},"n1520":{"id":"n1520","loc":[-85.631231,41.957618]},"n1521":{"id":"n1521","loc":[-85.63129,41.957618]},"n1522":{"id":"n1522","loc":[-85.63129,41.957651]},"n1523":{"id":"n1523","loc":[-85.631346,41.957651]},"n1524":{"id":"n1524","loc":[-85.631366,41.95802]},"n1525":{"id":"n1525","loc":[-85.631141,41.958021]},"n1526":{"id":"n1526","loc":[-85.63114,41.957943]},"n1527":{"id":"n1527","loc":[-85.631167,41.957943]},"n1528":{"id":"n1528","loc":[-85.631166,41.957808]},"n1529":{"id":"n1529","loc":[-85.631301,41.957807]},"n153":{"id":"n153","loc":[-85.63763,41.942528]},"n1530":{"id":"n1530","loc":[-85.631302,41.95789]},"n1531":{"id":"n1531","loc":[-85.631364,41.95789]},"n1532":{"id":"n1532","loc":[-85.631539,41.957754]},"n1533":{"id":"n1533","loc":[-85.631069,41.957756]},"n1534":{"id":"n1534","loc":[-85.631536,41.957518]},"n1535":{"id":"n1535","loc":[-85.631543,41.957995]},"n1536":{"id":"n1536","loc":[-85.631531,41.957748]},"n1537":{"id":"n1537","loc":[-85.631485,41.957748]},"n1538":{"id":"n1538","loc":[-85.631484,41.957698]},"n1539":{"id":"n1539","loc":[-85.631531,41.957698]},"n154":{"id":"n154","loc":[-85.637151,41.94253]},"n1540":{"id":"n1540","loc":[-85.631586,41.957742]},"n1541":{"id":"n1541","loc":[-85.63155,41.957742]},"n1542":{"id":"n1542","loc":[-85.631551,41.957702]},"n1543":{"id":"n1543","loc":[-85.631587,41.957702]},"n1544":{"id":"n1544","loc":[-85.631534,41.95807]},"n1545":{"id":"n1545","loc":[-85.631534,41.958097]},"n1546":{"id":"n1546","loc":[-85.631491,41.958097]},"n1547":{"id":"n1547","loc":[-85.631491,41.95807]},"n1548":{"id":"n1548","loc":[-85.631304,41.958861]},"n1549":{"id":"n1549","loc":[-85.631186,41.958862]},"n155":{"id":"n155","loc":[-85.63715,41.942424]},"n1550":{"id":"n1550","loc":[-85.631182,41.958653]},"n1551":{"id":"n1551","loc":[-85.6313,41.958651]},"n1552":{"id":"n1552","loc":[-85.631293,41.95854]},"n1553":{"id":"n1553","loc":[-85.631176,41.958539]},"n1554":{"id":"n1554","loc":[-85.631176,41.958377]},"n1555":{"id":"n1555","loc":[-85.631297,41.958377]},"n1556":{"id":"n1556","loc":[-85.631297,41.958422]},"n1557":{"id":"n1557","loc":[-85.631333,41.958422]},"n1558":{"id":"n1558","loc":[-85.631333,41.958479]},"n1559":{"id":"n1559","loc":[-85.631293,41.958479]},"n156":{"id":"n156","loc":[-85.637629,41.942422]},"n1560":{"id":"n1560","loc":[-85.631951,41.958908]},"n1561":{"id":"n1561","loc":[-85.631838,41.958909]},"n1562":{"id":"n1562","loc":[-85.631837,41.958847]},"n1563":{"id":"n1563","loc":[-85.631859,41.958847]},"n1564":{"id":"n1564","loc":[-85.631858,41.958746]},"n1565":{"id":"n1565","loc":[-85.631961,41.958745]},"n1566":{"id":"n1566","loc":[-85.631962,41.958812]},"n1567":{"id":"n1567","loc":[-85.631949,41.958813]},"n1568":{"id":"n1568","loc":[-85.631579,41.958913]},"n1569":{"id":"n1569","loc":[-85.631567,41.95864]},"n157":{"id":"n157","loc":[-85.638232,41.942477]},"n1570":{"id":"n1570","loc":[-85.631942,41.958639]},"n1571":{"id":"n1571","loc":[-85.631543,41.958594]},"n1572":{"id":"n1572","loc":[-85.631543,41.958065]},"n1573":{"id":"n1573","loc":[-85.631888,41.958546]},"n1574":{"id":"n1574","loc":[-85.631804,41.958546]},"n1575":{"id":"n1575","loc":[-85.631803,41.95841]},"n1576":{"id":"n1576","loc":[-85.631886,41.958409]},"n1577":{"id":"n1577","loc":[-85.631897,41.958125]},"n1578":{"id":"n1578","loc":[-85.631755,41.958126]},"n1579":{"id":"n1579","loc":[-85.631756,41.958174]},"n158":{"id":"n158","loc":[-85.637775,41.942483]},"n1580":{"id":"n1580","loc":[-85.63178,41.958174]},"n1581":{"id":"n1581","loc":[-85.631782,41.958272]},"n1582":{"id":"n1582","loc":[-85.631922,41.958271]},"n1583":{"id":"n1583","loc":[-85.631922,41.958244]},"n1584":{"id":"n1584","loc":[-85.631883,41.958245]},"n1585":{"id":"n1585","loc":[-85.631882,41.958175]},"n1586":{"id":"n1586","loc":[-85.631898,41.958175]},"n1587":{"id":"n1587","loc":[-85.631924,41.958032]},"n1588":{"id":"n1588","loc":[-85.631762,41.958032]},"n1589":{"id":"n1589","loc":[-85.63176,41.957827]},"n159":{"id":"n159","loc":[-85.638107,41.942512]},"n1590":{"id":"n1590","loc":[-85.631888,41.957826]},"n1591":{"id":"n1591","loc":[-85.631888,41.957892]},"n1592":{"id":"n1592","loc":[-85.631871,41.957892]},"n1593":{"id":"n1593","loc":[-85.631872,41.957949]},"n1594":{"id":"n1594","loc":[-85.631923,41.957949]},"n1595":{"id":"n1595","loc":[-85.631695,41.95795]},"n1596":{"id":"n1596","loc":[-85.631666,41.957975]},"n1597":{"id":"n1597","loc":[-85.63163,41.957975]},"n1598":{"id":"n1598","loc":[-85.6316,41.957951]},"n1599":{"id":"n1599","loc":[-85.6316,41.95785]},"n16":{"id":"n16","loc":[-85.63341,41.94032]},"n160":{"id":"n160","loc":[-85.637763,41.942514]},"n1600":{"id":"n1600","loc":[-85.63166,41.95785]},"n1601":{"id":"n1601","loc":[-85.631696,41.957873]},"n1602":{"id":"n1602","loc":[-85.631924,41.957762]},"n1603":{"id":"n1603","loc":[-85.631762,41.957762]},"n1604":{"id":"n1604","loc":[-85.631762,41.957708]},"n1605":{"id":"n1605","loc":[-85.631785,41.957708]},"n1606":{"id":"n1606","loc":[-85.631785,41.957606]},"n1607":{"id":"n1607","loc":[-85.631734,41.957606]},"n1608":{"id":"n1608","loc":[-85.631734,41.957538]},"n1609":{"id":"n1609","loc":[-85.631821,41.957538]},"n161":{"id":"n161","loc":[-85.637763,41.942445]},"n1610":{"id":"n1610","loc":[-85.631935,41.957545]},"n1611":{"id":"n1611","loc":[-85.631821,41.957544]},"n1612":{"id":"n1612","loc":[-85.631935,41.957645]},"n1613":{"id":"n1613","loc":[-85.631924,41.957645]},"n1614":{"id":"n1614","loc":[-85.627135,41.953828]},"n1615":{"id":"n1615","loc":[-85.633517,41.941353],"tags":{"man_made":"lighthouse"}},"n1616":{"id":"n1616","loc":[-85.633659,41.942041],"tags":{"amenity":"bbq"}},"n1617":{"id":"n1617","loc":[-85.63662,41.942911],"tags":{"amenity":"toilets"}},"n1618":{"id":"n1618","loc":[-85.637487,41.943876],"tags":{"amenity":"toilets"}},"n1619":{"id":"n1619","loc":[-85.634938,41.941917],"tags":{"amenity":"toilets"}},"n162":{"id":"n162","loc":[-85.638107,41.942443]},"n1620":{"id":"n1620","loc":[-85.632427,41.941678],"tags":{"amenity":"bbq"}},"n1621":{"id":"n1621","loc":[-85.638033,41.944568],"tags":{"amenity":"bbq"}},"n1622":{"id":"n1622","loc":[-85.638052,41.944522],"tags":{"amenity":"bbq"}},"n1623":{"id":"n1623","loc":[-85.635001,41.941965]},"n1624":{"id":"n1624","loc":[-85.634635,41.941884]},"n1625":{"id":"n1625","loc":[-85.634667,41.941894]},"n1626":{"id":"n1626","loc":[-85.634791,41.942011]},"n1627":{"id":"n1627","loc":[-85.634749,41.941938]},"n1628":{"id":"n1628","loc":[-85.627295,41.953946],"tags":{"barrier":"gate"}},"n1629":{"id":"n1629","loc":[-85.629076,41.954689]},"n163":{"id":"n163","loc":[-85.638813,41.942475]},"n1630":{"id":"n1630","loc":[-85.640667,41.942595]},"n1631":{"id":"n1631","loc":[-85.639455,41.94261]},"n1632":{"id":"n1632","loc":[-85.643407,41.942336]},"n1633":{"id":"n1633","loc":[-85.641845,41.941316]},"n1634":{"id":"n1634","loc":[-85.643322,41.942224]},"n1635":{"id":"n1635","loc":[-85.643301,41.942124]},"n1636":{"id":"n1636","loc":[-85.640639,41.941326]},"n1637":{"id":"n1637","loc":[-85.640614,41.940058]},"n1638":{"id":"n1638","loc":[-85.639428,41.941335]},"n1639":{"id":"n1639","loc":[-85.643078,41.941293]},"n164":{"id":"n164","loc":[-85.63883,41.942422]},"n1640":{"id":"n1640","loc":[-85.64371,41.942302]},"n1641":{"id":"n1641","loc":[-85.643056,41.94001]},"n1642":{"id":"n1642","loc":[-85.643097,41.942575],"tags":{"highway":"traffic_signals","traffic_signals":"signal"}},"n1643":{"id":"n1643","loc":[-85.641855,41.942586]},"n1644":{"id":"n1644","loc":[-85.643549,41.942209]},"n1645":{"id":"n1645","loc":[-85.639359,41.94007]},"n1646":{"id":"n1646","loc":[-85.642797,41.940522]},"n1647":{"id":"n1647","loc":[-85.642589,41.940523]},"n1648":{"id":"n1648","loc":[-85.642587,41.940287]},"n1649":{"id":"n1649","loc":[-85.642797,41.940286]},"n165":{"id":"n165","loc":[-85.63883,41.942508]},"n1650":{"id":"n1650","loc":[-85.642571,41.940523]},"n1651":{"id":"n1651","loc":[-85.642568,41.940286]},"n1652":{"id":"n1652","loc":[-85.642316,41.940289]},"n1653":{"id":"n1653","loc":[-85.642321,41.940436]},"n1654":{"id":"n1654","loc":[-85.642292,41.940458]},"n1655":{"id":"n1655","loc":[-85.642287,41.940483]},"n1656":{"id":"n1656","loc":[-85.642323,41.940509]},"n1657":{"id":"n1657","loc":[-85.642385,41.940511]},"n1658":{"id":"n1658","loc":[-85.642408,41.940526]},"n1659":{"id":"n1659","loc":[-85.641962,41.94109]},"n166":{"id":"n166","loc":[-85.638364,41.942508]},"n1660":{"id":"n1660","loc":[-85.642753,41.941084]},"n1661":{"id":"n1661","loc":[-85.642752,41.941004]},"n1662":{"id":"n1662","loc":[-85.642806,41.941003]},"n1663":{"id":"n1663","loc":[-85.642803,41.940731]},"n1664":{"id":"n1664","loc":[-85.642741,41.940732]},"n1665":{"id":"n1665","loc":[-85.64274,41.940645]},"n1666":{"id":"n1666","loc":[-85.641957,41.940651]},"n1667":{"id":"n1667","loc":[-85.642937,41.941241]},"n1668":{"id":"n1668","loc":[-85.641776,41.941253]},"n1669":{"id":"n1669","loc":[-85.641766,41.940598]},"n167":{"id":"n167","loc":[-85.638836,41.942167]},"n1670":{"id":"n1670","loc":[-85.64198,41.940598]},"n1671":{"id":"n1671","loc":[-85.641961,41.940137]},"n1672":{"id":"n1672","loc":[-85.642934,41.94012]},"n1673":{"id":"n1673","loc":[-85.643074,41.941173]},"n1674":{"id":"n1674","loc":[-85.642841,41.940997]},"n1675":{"id":"n1675","loc":[-85.642839,41.940721]},"n1676":{"id":"n1676","loc":[-85.643065,41.940552]},"n1677":{"id":"n1677","loc":[-85.642732,41.94124]},"n1678":{"id":"n1678","loc":[-85.641815,41.941246]},"n1679":{"id":"n1679","loc":[-85.641813,41.941132]},"n168":{"id":"n168","loc":[-85.638836,41.94229]},"n1680":{"id":"n1680","loc":[-85.641839,41.941111]},"n1681":{"id":"n1681","loc":[-85.641884,41.941098]},"n1682":{"id":"n1682","loc":[-85.642732,41.941092]},"n1683":{"id":"n1683","loc":[-85.642776,41.941302]},"n1684":{"id":"n1684","loc":[-85.632788,41.946236]},"n1685":{"id":"n1685","loc":[-85.622342,41.953127]},"n1686":{"id":"n1686","loc":[-85.641848,41.941167]},"n1687":{"id":"n1687","loc":[-85.643753,41.941503]},"n1688":{"id":"n1688","loc":[-85.643762,41.942119]},"n1689":{"id":"n1689","loc":[-85.64238,41.942262]},"n169":{"id":"n169","loc":[-85.638594,41.94229]},"n1690":{"id":"n1690","loc":[-85.642374,41.941944]},"n1691":{"id":"n1691","loc":[-85.642518,41.941943]},"n1692":{"id":"n1692","loc":[-85.642519,41.94198]},"n1693":{"id":"n1693","loc":[-85.642831,41.941977]},"n1694":{"id":"n1694","loc":[-85.642837,41.942312]},"n1695":{"id":"n1695","loc":[-85.642495,41.942315]},"n1696":{"id":"n1696","loc":[-85.642494,41.942261]},"n1697":{"id":"n1697","loc":[-85.641087,41.942433]},"n1698":{"id":"n1698","loc":[-85.641081,41.942006]},"n1699":{"id":"n1699","loc":[-85.641244,41.942005]},"n17":{"id":"n17","loc":[-85.633478,41.94081]},"n170":{"id":"n170","loc":[-85.638594,41.942422]},"n1700":{"id":"n1700","loc":[-85.64125,41.942431]},"n1701":{"id":"n1701","loc":[-85.641331,41.942968]},"n1702":{"id":"n1702","loc":[-85.641328,41.942713]},"n1703":{"id":"n1703","loc":[-85.641521,41.942712]},"n1704":{"id":"n1704","loc":[-85.641523,41.942924]},"n1705":{"id":"n1705","loc":[-85.641504,41.942924]},"n1706":{"id":"n1706","loc":[-85.641505,41.942967]},"n1707":{"id":"n1707","loc":[-85.638612,41.942408]},"n1708":{"id":"n1708","loc":[-85.638612,41.942327]},"n1709":{"id":"n1709","loc":[-85.638775,41.942327]},"n171":{"id":"n171","loc":[-85.638364,41.942356]},"n1710":{"id":"n1710","loc":[-85.638775,41.942299]},"n1711":{"id":"n1711","loc":[-85.638835,41.942298]},"n1712":{"id":"n1712","loc":[-85.638835,41.942407]},"n1713":{"id":"n1713","loc":[-85.639116,41.942444]},"n1714":{"id":"n1714","loc":[-85.639114,41.942362]},"n1715":{"id":"n1715","loc":[-85.639294,41.94236]},"n1716":{"id":"n1716","loc":[-85.639296,41.942442]},"n1717":{"id":"n1717","loc":[-85.639808,41.942385]},"n1718":{"id":"n1718","loc":[-85.639805,41.942285]},"n1719":{"id":"n1719","loc":[-85.639988,41.942283]},"n172":{"id":"n172","loc":[-85.638364,41.942167]},"n1720":{"id":"n1720","loc":[-85.63999,41.942383]},"n1721":{"id":"n1721","loc":[-85.639633,41.943023]},"n1722":{"id":"n1722","loc":[-85.639867,41.943019]},"n1723":{"id":"n1723","loc":[-85.639866,41.942964]},"n1724":{"id":"n1724","loc":[-85.639888,41.942963]},"n1725":{"id":"n1725","loc":[-85.639883,41.942779]},"n1726":{"id":"n1726","loc":[-85.639851,41.94278]},"n1727":{"id":"n1727","loc":[-85.63985,41.94274]},"n1728":{"id":"n1728","loc":[-85.639789,41.942741]},"n1729":{"id":"n1729","loc":[-85.639789,41.942753]},"n173":{"id":"n173","loc":[-85.639038,41.942463]},"n1730":{"id":"n1730","loc":[-85.639698,41.942754]},"n1731":{"id":"n1731","loc":[-85.639699,41.942788]},"n1732":{"id":"n1732","loc":[-85.639675,41.942789]},"n1733":{"id":"n1733","loc":[-85.639676,41.94283]},"n1734":{"id":"n1734","loc":[-85.639701,41.942829]},"n1735":{"id":"n1735","loc":[-85.639702,41.942869]},"n1736":{"id":"n1736","loc":[-85.639629,41.94287]},"n1737":{"id":"n1737","loc":[-85.643568,41.942946]},"n1738":{"id":"n1738","loc":[-85.643568,41.942777]},"n1739":{"id":"n1739","loc":[-85.643401,41.942777]},"n174":{"id":"n174","loc":[-85.638897,41.942464]},"n1740":{"id":"n1740","loc":[-85.643401,41.942863]},"n1741":{"id":"n1741","loc":[-85.643448,41.942863]},"n1742":{"id":"n1742","loc":[-85.643448,41.942946]},"n1743":{"id":"n1743","loc":[-85.642836,41.942981]},"n1744":{"id":"n1744","loc":[-85.642917,41.942979]},"n1745":{"id":"n1745","loc":[-85.642914,41.942904]},"n1746":{"id":"n1746","loc":[-85.642938,41.942903]},"n1747":{"id":"n1747","loc":[-85.642935,41.942813]},"n1748":{"id":"n1748","loc":[-85.642775,41.942816]},"n1749":{"id":"n1749","loc":[-85.642778,41.942906]},"n175":{"id":"n175","loc":[-85.638897,41.942423]},"n1750":{"id":"n1750","loc":[-85.642833,41.942905]},"n1751":{"id":"n1751","loc":[-85.642302,41.942886]},"n1752":{"id":"n1752","loc":[-85.642299,41.942721]},"n1753":{"id":"n1753","loc":[-85.642422,41.94272]},"n1754":{"id":"n1754","loc":[-85.642425,41.942868]},"n1755":{"id":"n1755","loc":[-85.642385,41.942869]},"n1756":{"id":"n1756","loc":[-85.642385,41.942885]},"n1757":{"id":"n1757","loc":[-85.641533,41.942939]},"n1758":{"id":"n1758","loc":[-85.64161,41.942877]},"n1759":{"id":"n1759","loc":[-85.641676,41.942922]},"n176":{"id":"n176","loc":[-85.638853,41.942423]},"n1760":{"id":"n1760","loc":[-85.6416,41.942985]},"n1761":{"id":"n1761","loc":[-85.64206,41.942802]},"n1762":{"id":"n1762","loc":[-85.642059,41.942741]},"n1763":{"id":"n1763","loc":[-85.642196,41.942741]},"n1764":{"id":"n1764","loc":[-85.642196,41.942818]},"n1765":{"id":"n1765","loc":[-85.642128,41.942819]},"n1766":{"id":"n1766","loc":[-85.642128,41.942801]},"n1767":{"id":"n1767","loc":[-85.640943,41.942934]},"n1768":{"id":"n1768","loc":[-85.641035,41.942933]},"n1769":{"id":"n1769","loc":[-85.641032,41.942797]},"n177":{"id":"n177","loc":[-85.638852,41.94237]},"n1770":{"id":"n1770","loc":[-85.640997,41.942798]},"n1771":{"id":"n1771","loc":[-85.640996,41.942764]},"n1772":{"id":"n1772","loc":[-85.640861,41.942766]},"n1773":{"id":"n1773","loc":[-85.640862,41.942848]},"n1774":{"id":"n1774","loc":[-85.640941,41.942847]},"n1775":{"id":"n1775","loc":[-85.643766,41.942226]},"n1776":{"id":"n1776","loc":[-85.643768,41.942407]},"n1777":{"id":"n1777","loc":[-85.643218,41.94177]},"n1778":{"id":"n1778","loc":[-85.64321,41.941327]},"n1779":{"id":"n1779","loc":[-85.643649,41.941323]},"n178":{"id":"n178","loc":[-85.638892,41.94237]},"n1780":{"id":"n1780","loc":[-85.643656,41.941716]},"n1781":{"id":"n1781","loc":[-85.64358,41.941717]},"n1782":{"id":"n1782","loc":[-85.64358,41.941767]},"n1783":{"id":"n1783","loc":[-85.64382,41.941495]},"n1784":{"id":"n1784","loc":[-85.643817,41.941317]},"n1785":{"id":"n1785","loc":[-85.643235,41.941833]},"n1786":{"id":"n1786","loc":[-85.64335,41.941842]},"n1787":{"id":"n1787","loc":[-85.643504,41.941903]},"n1788":{"id":"n1788","loc":[-85.643554,41.941946]},"n1789":{"id":"n1789","loc":[-85.643618,41.942015]},"n179":{"id":"n179","loc":[-85.638891,41.942334]},"n1790":{"id":"n1790","loc":[-85.64346,41.941971]},"n1791":{"id":"n1791","loc":[-85.643528,41.942468]},"n1792":{"id":"n1792","loc":[-85.643621,41.942363]},"n1793":{"id":"n1793","loc":[-85.643496,41.942297]},"n1794":{"id":"n1794","loc":[-85.643446,41.942246]},"n1795":{"id":"n1795","loc":[-85.643398,41.942177]},"n1796":{"id":"n1796","loc":[-85.643398,41.942031]},"n1797":{"id":"n1797","loc":[-85.621531,41.952693]},"n1798":{"id":"n1798","loc":[-85.643221,41.942028]},"n1799":{"id":"n1799","loc":[-85.643225,41.942276]},"n18":{"id":"n18","loc":[-85.63345,41.94071]},"n180":{"id":"n180","loc":[-85.639037,41.942334]},"n1800":{"id":"n1800","loc":[-85.643265,41.942347]},"n1801":{"id":"n1801","loc":[-85.643323,41.942413]},"n1802":{"id":"n1802","loc":[-85.643411,41.94247]},"n1803":{"id":"n1803","loc":[-85.643459,41.942435]},"n1804":{"id":"n1804","loc":[-85.643767,41.942307]},"n1805":{"id":"n1805","loc":[-85.643661,41.942293]},"n1806":{"id":"n1806","loc":[-85.643578,41.942247]},"n1807":{"id":"n1807","loc":[-85.643522,41.942125]},"n1808":{"id":"n1808","loc":[-85.643515,41.942061]},"n1809":{"id":"n1809","loc":[-85.643346,41.941924]},"n181":{"id":"n181","loc":[-85.638074,41.941839]},"n1810":{"id":"n1810","loc":[-85.643086,41.94192]},"n1811":{"id":"n1811","loc":[-85.643529,41.94217]},"n1812":{"id":"n1812","loc":[-85.643489,41.942003]},"n1813":{"id":"n1813","loc":[-85.643295,41.941919]},"n1814":{"id":"n1814","loc":[-85.643305,41.942163]},"n1815":{"id":"n1815","loc":[-85.643354,41.942285]},"n1816":{"id":"n1816","loc":[-85.643472,41.942389]},"n1817":{"id":"n1817","loc":[-85.643608,41.942271]},"n1818":{"id":"n1818","loc":[-85.643876,41.941402]},"n1819":{"id":"n1819","loc":[-85.643818,41.941369]},"n182":{"id":"n182","loc":[-85.638076,41.941942]},"n1820":{"id":"n1820","loc":[-85.643682,41.941304]},"n1821":{"id":"n1821","loc":[-85.64359,41.941286]},"n1822":{"id":"n1822","loc":[-85.643317,41.941727]},"n1823":{"id":"n1823","loc":[-85.643301,41.941286]},"n1824":{"id":"n1824","loc":[-85.643553,41.941698]},"n1825":{"id":"n1825","loc":[-85.643543,41.941286]},"n1826":{"id":"n1826","loc":[-85.636967,41.940118]},"n1827":{"id":"n1827","loc":[-85.63378,41.940114]},"n1828":{"id":"n1828","loc":[-85.637254,41.940075]},"n1829":{"id":"n1829","loc":[-85.637002,41.941355]},"n183":{"id":"n183","loc":[-85.637955,41.941944]},"n1830":{"id":"n1830","loc":[-85.643532,41.94204]},"n1831":{"id":"n1831","loc":[-85.638235,41.942615]},"n1832":{"id":"n1832","loc":[-85.637039,41.942624]},"n1833":{"id":"n1833","loc":[-85.636369,41.94266]},"n1834":{"id":"n1834","loc":[-85.63582,41.942771],"tags":{"highway":"traffic_signals","traffic_signals":"emergency"}},"n1835":{"id":"n1835","loc":[-85.634873,41.943044]},"n1836":{"id":"n1836","loc":[-85.643482,41.941976]},"n1837":{"id":"n1837","loc":[-85.64345,41.941945]},"n1838":{"id":"n1838","loc":[-85.641885,41.943851]},"n1839":{"id":"n1839","loc":[-85.641915,41.945121]},"n184":{"id":"n184","loc":[-85.637953,41.94184]},"n1840":{"id":"n1840","loc":[-85.639454,41.943871]},"n1841":{"id":"n1841","loc":[-85.639491,41.945191]},"n1842":{"id":"n1842","loc":[-85.635768,41.940113]},"n1843":{"id":"n1843","loc":[-85.638206,41.941345]},"n1844":{"id":"n1844","loc":[-85.640721,41.94513]},"n1845":{"id":"n1845","loc":[-85.643137,41.945103]},"n1846":{"id":"n1846","loc":[-85.638199,41.940079]},"n1847":{"id":"n1847","loc":[-85.640688,41.943861]},"n1848":{"id":"n1848","loc":[-85.643397,41.941924]},"n1849":{"id":"n1849","loc":[-85.643117,41.943841]},"n185":{"id":"n185","loc":[-85.637953,41.941866]},"n1850":{"id":"n1850","loc":[-85.636731,41.94263]},"n1851":{"id":"n1851","loc":[-85.63518,41.942955],"tags":{"highway":"crossing"}},"n1852":{"id":"n1852","loc":[-85.636152,41.942695]},"n1853":{"id":"n1853","loc":[-85.644202,41.941499]},"n1854":{"id":"n1854","loc":[-85.644211,41.942116]},"n1855":{"id":"n1855","loc":[-85.644233,41.942404]},"n1856":{"id":"n1856","loc":[-85.644231,41.942223]},"n1857":{"id":"n1857","loc":[-85.644133,41.941315]},"n1858":{"id":"n1858","loc":[-85.644136,41.941493]},"n1859":{"id":"n1859","loc":[-85.644345,41.942307]},"n186":{"id":"n186","loc":[-85.637873,41.941867]},"n1860":{"id":"n1860","loc":[-85.644232,41.942304]},"n1861":{"id":"n1861","loc":[-85.644134,41.941403]},"n1862":{"id":"n1862","loc":[-85.63607,41.943005],"tags":{"addr:city":"Three Rivers","addr:housenumber":"333","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"fire_station","name":"Three Rivers Fire Department"}},"n1863":{"id":"n1863","loc":[-85.637,41.941236]},"n1864":{"id":"n1864","loc":[-85.634476,41.941475]},"n1865":{"id":"n1865","loc":[-85.635036,41.941858]},"n1866":{"id":"n1866","loc":[-85.635362,41.941962]},"n1867":{"id":"n1867","loc":[-85.635796,41.941962]},"n1868":{"id":"n1868","loc":[-85.63295,41.943006]},"n1869":{"id":"n1869","loc":[-85.634692,41.943098]},"n187":{"id":"n187","loc":[-85.637877,41.941975]},"n1870":{"id":"n1870","loc":[-85.633128,41.940484]},"n1871":{"id":"n1871","loc":[-85.633117,41.942798]},"n1872":{"id":"n1872","loc":[-85.633303,41.942412]},"n1873":{"id":"n1873","loc":[-85.633482,41.941912]},"n1874":{"id":"n1874","loc":[-85.633455,41.941359]},"n1875":{"id":"n1875","loc":[-85.633162,41.942679]},"n1876":{"id":"n1876","loc":[-85.634274,41.943479]},"n1877":{"id":"n1877","loc":[-85.634678,41.942909]},"n1878":{"id":"n1878","loc":[-85.6339,41.941453]},"n1879":{"id":"n1879","loc":[-85.634571,41.942774]},"n188":{"id":"n188","loc":[-85.636855,41.942488]},"n1880":{"id":"n1880","loc":[-85.63419,41.941732]},"n1881":{"id":"n1881","loc":[-85.634067,41.941565]},"n1882":{"id":"n1882","loc":[-85.63436,41.942358]},"n1883":{"id":"n1883","loc":[-85.634327,41.942247]},"n1884":{"id":"n1884","loc":[-85.633391,41.941231]},"n1885":{"id":"n1885","loc":[-85.634303,41.941972]},"n1886":{"id":"n1886","loc":[-85.633541,41.940147]},"n1887":{"id":"n1887","loc":[-85.633433,41.940252]},"n1888":{"id":"n1888","loc":[-85.633402,41.940411]},"n1889":{"id":"n1889","loc":[-85.633551,41.941023]},"n189":{"id":"n189","loc":[-85.636702,41.942488]},"n1890":{"id":"n1890","loc":[-85.633719,41.941186]},"n1891":{"id":"n1891","loc":[-85.633067,41.941845]},"n1892":{"id":"n1892","loc":[-85.634902,41.942766]},"n1893":{"id":"n1893","loc":[-85.634603,41.942202]},"n1894":{"id":"n1894","loc":[-85.634858,41.942152]},"n1895":{"id":"n1895","loc":[-85.634842,41.942269]},"n1896":{"id":"n1896","loc":[-85.634907,41.942313]},"n1897":{"id":"n1897","loc":[-85.635049,41.942331]},"n1898":{"id":"n1898","loc":[-85.635101,41.942281]},"n1899":{"id":"n1899","loc":[-85.635129,41.942144]},"n19":{"id":"n19","loc":[-85.633009,41.942229]},"n190":{"id":"n190","loc":[-85.636702,41.942434]},"n1900":{"id":"n1900","loc":[-85.635531,41.942143]},"n1901":{"id":"n1901","loc":[-85.635534,41.942577]},"n1902":{"id":"n1902","loc":[-85.635158,41.942656]},"n1903":{"id":"n1903","loc":[-85.635121,41.942703]},"n1904":{"id":"n1904","loc":[-85.635087,41.941508]},"n1905":{"id":"n1905","loc":[-85.63536,41.941106]},"n1906":{"id":"n1906","loc":[-85.635442,41.941094]},"n1907":{"id":"n1907","loc":[-85.635508,41.941104]},"n1908":{"id":"n1908","loc":[-85.635569,41.941125]},"n1909":{"id":"n1909","loc":[-85.635583,41.941106]},"n191":{"id":"n191","loc":[-85.636761,41.942434]},"n1910":{"id":"n1910","loc":[-85.635555,41.940976]},"n1911":{"id":"n1911","loc":[-85.635501,41.940915]},"n1912":{"id":"n1912","loc":[-85.635392,41.940922]},"n1913":{"id":"n1913","loc":[-85.635276,41.940974]},"n1914":{"id":"n1914","loc":[-85.63517,41.941204]},"n1915":{"id":"n1915","loc":[-85.634888,41.941517]},"n1916":{"id":"n1916","loc":[-85.634897,41.941576]},"n1917":{"id":"n1917","loc":[-85.634961,41.94164]},"n1918":{"id":"n1918","loc":[-85.635028,41.941659]},"n1919":{"id":"n1919","loc":[-85.635118,41.941621]},"n192":{"id":"n192","loc":[-85.636761,41.942369]},"n1920":{"id":"n1920","loc":[-85.635085,41.941558]},"n1921":{"id":"n1921","loc":[-85.63504,41.94136]},"n1922":{"id":"n1922","loc":[-85.635221,41.941077]},"n1923":{"id":"n1923","loc":[-85.634387,41.941559]},"n1924":{"id":"n1924","loc":[-85.634351,41.941587]},"n1925":{"id":"n1925","loc":[-85.634416,41.941756]},"n1926":{"id":"n1926","loc":[-85.634461,41.941797]},"n1927":{"id":"n1927","loc":[-85.634501,41.941819]},"n1928":{"id":"n1928","loc":[-85.634597,41.941816]},"n1929":{"id":"n1929","loc":[-85.634732,41.941724]},"n193":{"id":"n193","loc":[-85.636855,41.942369]},"n1930":{"id":"n1930","loc":[-85.634672,41.941775]},"n1931":{"id":"n1931","loc":[-85.633403,41.939101]},"n1932":{"id":"n1932","loc":[-85.633297,41.939397]},"n1933":{"id":"n1933","loc":[-85.633205,41.939674]},"n1934":{"id":"n1934","loc":[-85.63322,41.939777]},"n1935":{"id":"n1935","loc":[-85.633345,41.939936]},"n1936":{"id":"n1936","loc":[-85.633376,41.940002]},"n1937":{"id":"n1937","loc":[-85.633266,41.940228]},"n1938":{"id":"n1938","loc":[-85.633236,41.940352]},"n1939":{"id":"n1939","loc":[-85.633282,41.94063]},"n194":{"id":"n194","loc":[-85.636645,41.94249]},"n1940":{"id":"n1940","loc":[-85.633364,41.940874]},"n1941":{"id":"n1941","loc":[-85.633439,41.941052]},"n1942":{"id":"n1942","loc":[-85.633582,41.941172]},"n1943":{"id":"n1943","loc":[-85.633748,41.941273]},"n1944":{"id":"n1944","loc":[-85.634317,41.941527]},"n1945":{"id":"n1945","loc":[-85.634389,41.94174]},"n1946":{"id":"n1946","loc":[-85.634441,41.941801]},"n1947":{"id":"n1947","loc":[-85.634514,41.941837]},"n1948":{"id":"n1948","loc":[-85.634485,41.942005]},"n1949":{"id":"n1949","loc":[-85.63457,41.942202]},"n195":{"id":"n195","loc":[-85.636565,41.94249]},"n1950":{"id":"n1950","loc":[-85.634869,41.942769]},"n1951":{"id":"n1951","loc":[-85.634943,41.942792]},"n1952":{"id":"n1952","loc":[-85.635139,41.942882]},"n1953":{"id":"n1953","loc":[-85.634962,41.943161]},"n1954":{"id":"n1954","loc":[-85.635002,41.943131]},"n1955":{"id":"n1955","loc":[-85.635005,41.943091]},"n1956":{"id":"n1956","loc":[-85.635216,41.943033]},"n1957":{"id":"n1957","loc":[-85.634817,41.94267]},"n1958":{"id":"n1958","loc":[-85.634614,41.942599]},"n1959":{"id":"n1959","loc":[-85.634494,41.942381]},"n196":{"id":"n196","loc":[-85.636565,41.942474]},"n1960":{"id":"n1960","loc":[-85.634486,41.9423]},"n1961":{"id":"n1961","loc":[-85.634671,41.941795]},"n1962":{"id":"n1962","loc":[-85.634595,41.941831]},"n1963":{"id":"n1963","loc":[-85.634332,41.941866]},"n1964":{"id":"n1964","loc":[-85.634207,41.941885]},"n1965":{"id":"n1965","loc":[-85.634133,41.941892]},"n1966":{"id":"n1966","loc":[-85.634131,41.942203]},"n1967":{"id":"n1967","loc":[-85.634047,41.942327]},"n1968":{"id":"n1968","loc":[-85.634219,41.942793]},"n1969":{"id":"n1969","loc":[-85.634061,41.942392]},"n197":{"id":"n197","loc":[-85.636514,41.942474]},"n1970":{"id":"n1970","loc":[-85.633989,41.942407]},"n1971":{"id":"n1971","loc":[-85.633971,41.942356]},"n1972":{"id":"n1972","loc":[-85.63361,41.942423]},"n1973":{"id":"n1973","loc":[-85.633714,41.942682]},"n1974":{"id":"n1974","loc":[-85.633698,41.942863]},"n1975":{"id":"n1975","loc":[-85.633882,41.942865]},"n1976":{"id":"n1976","loc":[-85.633941,41.943007]},"n1977":{"id":"n1977","loc":[-85.633887,41.943035]},"n1978":{"id":"n1978","loc":[-85.633768,41.942815]},"n1979":{"id":"n1979","loc":[-85.633682,41.942351]},"n198":{"id":"n198","loc":[-85.636514,41.942326]},"n1980":{"id":"n1980","loc":[-85.634037,41.942273]},"n1981":{"id":"n1981","loc":[-85.634029,41.942252]},"n1982":{"id":"n1982","loc":[-85.633673,41.942331]},"n1983":{"id":"n1983","loc":[-85.634219,41.942571]},"n1984":{"id":"n1984","loc":[-85.634252,41.942565]},"n1985":{"id":"n1985","loc":[-85.634144,41.942299]},"n1986":{"id":"n1986","loc":[-85.634115,41.942306]},"n1987":{"id":"n1987","loc":[-85.634059,41.943094]},"n1988":{"id":"n1988","loc":[-85.633944,41.942903]},"n1989":{"id":"n1989","loc":[-85.634311,41.942821]},"n199":{"id":"n199","loc":[-85.636561,41.942326]},"n1990":{"id":"n1990","loc":[-85.634351,41.94277]},"n1991":{"id":"n1991","loc":[-85.634153,41.942254]},"n1992":{"id":"n1992","loc":[-85.634092,41.94222]},"n1993":{"id":"n1993","loc":[-85.633571,41.942336]},"n1994":{"id":"n1994","loc":[-85.633513,41.942387]},"n1995":{"id":"n1995","loc":[-85.633509,41.942455]},"n1996":{"id":"n1996","loc":[-85.63363,41.942665]},"n1997":{"id":"n1997","loc":[-85.63414,41.94286]},"n1998":{"id":"n1998","loc":[-85.63397,41.942449]},"n1999":{"id":"n1999","loc":[-85.633551,41.942529]},"n2":{"id":"n2","loc":[-85.627421,41.953877]},"n20":{"id":"n20","loc":[-85.633013,41.941438]},"n200":{"id":"n200","loc":[-85.636561,41.942311]},"n2000":{"id":"n2000","loc":[-85.633741,41.942493]},"n2001":{"id":"n2001","loc":[-85.633894,41.942869]},"n2002":{"id":"n2002","loc":[-85.634132,41.941954]},"n2003":{"id":"n2003","loc":[-85.634032,41.942038]},"n2004":{"id":"n2004","loc":[-85.633765,41.942238]},"n2005":{"id":"n2005","loc":[-85.63376,41.942268]},"n2006":{"id":"n2006","loc":[-85.633768,41.942293]},"n2007":{"id":"n2007","loc":[-85.633808,41.942386]},"n2008":{"id":"n2008","loc":[-85.634946,41.941663]},"n2009":{"id":"n2009","loc":[-85.63511,41.941697]},"n201":{"id":"n201","loc":[-85.636621,41.942311]},"n2010":{"id":"n2010","loc":[-85.635337,41.94168]},"n2011":{"id":"n2011","loc":[-85.634997,41.942251]},"n2012":{"id":"n2012","loc":[-85.635013,41.942173]},"n2013":{"id":"n2013","loc":[-85.634876,41.942157]},"n2014":{"id":"n2014","loc":[-85.634859,41.942235]},"n2015":{"id":"n2015","loc":[-85.634992,41.941951]},"n2016":{"id":"n2016","loc":[-85.634952,41.941877]},"n2017":{"id":"n2017","loc":[-85.634844,41.94191]},"n2018":{"id":"n2018","loc":[-85.634884,41.941983]},"n2019":{"id":"n2019","loc":[-85.635189,41.941691]},"n202":{"id":"n202","loc":[-85.636621,41.942351]},"n2020":{"id":"n2020","loc":[-85.635089,41.941896]},"n2021":{"id":"n2021","loc":[-85.635077,41.941964]},"n2022":{"id":"n2022","loc":[-85.635058,41.942147]},"n2023":{"id":"n2023","loc":[-85.635099,41.942161]},"n2024":{"id":"n2024","loc":[-85.635099,41.942213]},"n2025":{"id":"n2025","loc":[-85.635079,41.942285]},"n2026":{"id":"n2026","loc":[-85.635047,41.942316]},"n2027":{"id":"n2027","loc":[-85.634925,41.9423]},"n2028":{"id":"n2028","loc":[-85.634911,41.942276]},"n2029":{"id":"n2029","loc":[-85.634917,41.942242]},"n203":{"id":"n203","loc":[-85.63666,41.942351]},"n2030":{"id":"n2030","loc":[-85.634698,41.941898]},"n2031":{"id":"n2031","loc":[-85.634964,41.941878]},"n2032":{"id":"n2032","loc":[-85.635025,41.941929]},"n2033":{"id":"n2033","loc":[-85.634862,41.941887]},"n2034":{"id":"n2034","loc":[-85.634811,41.94181]},"n2035":{"id":"n2035","loc":[-85.634731,41.941745]},"n2036":{"id":"n2036","loc":[-85.634933,41.94176]},"n2037":{"id":"n2037","loc":[-85.634942,41.942145]},"n2038":{"id":"n2038","loc":[-85.634944,41.942065]},"n2039":{"id":"n2039","loc":[-85.634914,41.941996]},"n204":{"id":"n204","loc":[-85.63666,41.942453]},"n2040":{"id":"n2040","loc":[-85.634981,41.941979]},"n2041":{"id":"n2041","loc":[-85.633419,41.942172]},"n2042":{"id":"n2042","loc":[-85.633509,41.941631]},"n2043":{"id":"n2043","loc":[-85.633686,41.942937]},"n2044":{"id":"n2044","loc":[-85.633371,41.942722]},"n2045":{"id":"n2045","loc":[-85.633291,41.942538]},"n2046":{"id":"n2046","loc":[-85.633902,41.940941]},"n2047":{"id":"n2047","loc":[-85.635254,41.940939]},"n2048":{"id":"n2048","loc":[-85.635686,41.940829]},"n2049":{"id":"n2049","loc":[-85.635712,41.942681]},"n205":{"id":"n205","loc":[-85.636645,41.942453]},"n2050":{"id":"n2050","loc":[-85.633721,41.942118]},"n2051":{"id":"n2051","loc":[-85.633698,41.942057]},"n2052":{"id":"n2052","loc":[-85.633591,41.942079]},"n2053":{"id":"n2053","loc":[-85.633614,41.94214]},"n2054":{"id":"n2054","loc":[-85.633968,41.941099]},"n2055":{"id":"n2055","loc":[-85.633907,41.941138]},"n2056":{"id":"n2056","loc":[-85.633968,41.941197]},"n2057":{"id":"n2057","loc":[-85.63404,41.941162]},"n2058":{"id":"n2058","loc":[-85.634839,41.941665]},"n2059":{"id":"n2059","loc":[-85.635314,41.943035]},"n206":{"id":"n206","loc":[-85.636394,41.942471]},"n2060":{"id":"n2060","loc":[-85.634919,41.943142]},"n2061":{"id":"n2061","loc":[-85.636433,41.942959],"tags":{"addr:city":"Three Rivers","addr:housenumber":"333","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"townhall","name":"Three Rivers City Hall"}},"n2062":{"id":"n2062","loc":[-85.637039,41.942789]},"n2063":{"id":"n2063","loc":[-85.636333,41.94279]},"n2064":{"id":"n2064","loc":[-85.634484,41.940726]},"n2065":{"id":"n2065","loc":[-85.634483,41.940603]},"n2066":{"id":"n2066","loc":[-85.634908,41.940601]},"n2067":{"id":"n2067","loc":[-85.634908,41.94053]},"n2068":{"id":"n2068","loc":[-85.634934,41.94053]},"n2069":{"id":"n2069","loc":[-85.634934,41.940496]},"n207":{"id":"n207","loc":[-85.636262,41.942472]},"n2070":{"id":"n2070","loc":[-85.63504,41.940495]},"n2071":{"id":"n2071","loc":[-85.63504,41.940531]},"n2072":{"id":"n2072","loc":[-85.635068,41.940531]},"n2073":{"id":"n2073","loc":[-85.635071,41.940794]},"n2074":{"id":"n2074","loc":[-85.635183,41.940793]},"n2075":{"id":"n2075","loc":[-85.635185,41.940916]},"n2076":{"id":"n2076","loc":[-85.634799,41.940919]},"n2077":{"id":"n2077","loc":[-85.634798,41.940798]},"n2078":{"id":"n2078","loc":[-85.634925,41.940797]},"n2079":{"id":"n2079","loc":[-85.634924,41.940724]},"n208":{"id":"n208","loc":[-85.636261,41.94233]},"n2080":{"id":"n2080","loc":[-85.637448,41.938233]},"n2081":{"id":"n2081","loc":[-85.634168,41.943279]},"n2082":{"id":"n2082","loc":[-85.635744,41.938248]},"n2083":{"id":"n2083","loc":[-85.638744,41.951211]},"n2084":{"id":"n2084","loc":[-85.636421,41.946392]},"n2085":{"id":"n2085","loc":[-85.635965,41.945809]},"n2086":{"id":"n2086","loc":[-85.635683,41.945449]},"n2087":{"id":"n2087","loc":[-85.635281,41.945025]},"n2088":{"id":"n2088","loc":[-85.632443,41.942574]},"n2089":{"id":"n2089","loc":[-85.638243,41.943674]},"n209":{"id":"n209","loc":[-85.636353,41.942329]},"n2090":{"id":"n2090","loc":[-85.638228,41.943747]},"n2091":{"id":"n2091","loc":[-85.638163,41.943797]},"n2092":{"id":"n2092","loc":[-85.638089,41.943832]},"n2093":{"id":"n2093","loc":[-85.637969,41.943841]},"n2094":{"id":"n2094","loc":[-85.637841,41.943833]},"n2095":{"id":"n2095","loc":[-85.637342,41.943734]},"n2096":{"id":"n2096","loc":[-85.637232,41.943707]},"n2097":{"id":"n2097","loc":[-85.637163,41.943668]},"n2098":{"id":"n2098","loc":[-85.637118,41.943615]},"n2099":{"id":"n2099","loc":[-85.637078,41.943494]},"n21":{"id":"n21","loc":[-85.634126,41.942228]},"n210":{"id":"n210","loc":[-85.636354,41.94239]},"n2100":{"id":"n2100","loc":[-85.632903,41.998429],"tags":{"railway":"level_crossing"}},"n2101":{"id":"n2101","loc":[-85.633616,41.943581],"tags":{"railway":"level_crossing"}},"n2102":{"id":"n2102","loc":[-85.636943,41.947311]},"n2103":{"id":"n2103","loc":[-85.6376,41.94854]},"n2104":{"id":"n2104","loc":[-85.634565,41.93631]},"n2105":{"id":"n2105","loc":[-85.629597,41.942562]},"n2106":{"id":"n2106","loc":[-85.630821,41.943077]},"n2107":{"id":"n2107","loc":[-85.627473,41.940659]},"n2108":{"id":"n2108","loc":[-85.629708,41.942872]},"n2109":{"id":"n2109","loc":[-85.634093,41.935448]},"n211":{"id":"n211","loc":[-85.636393,41.94239]},"n2110":{"id":"n2110","loc":[-85.630413,41.94366]},"n2111":{"id":"n2111","loc":[-85.630488,41.942662]},"n2112":{"id":"n2112","loc":[-85.63361,41.936749]},"n2113":{"id":"n2113","loc":[-85.630038,41.941808]},"n2114":{"id":"n2114","loc":[-85.632016,41.942922]},"n2115":{"id":"n2115","loc":[-85.631525,41.944303]},"n2116":{"id":"n2116","loc":[-85.626862,41.94022]},"n2117":{"id":"n2117","loc":[-85.629673,41.94121]},"n2118":{"id":"n2118","loc":[-85.632752,41.943101]},"n2119":{"id":"n2119","loc":[-85.631147,41.943201]},"n212":{"id":"n212","loc":[-85.63444,41.943176]},"n2120":{"id":"n2120","loc":[-85.624974,41.940579]},"n2121":{"id":"n2121","loc":[-85.629518,41.941783]},"n2122":{"id":"n2122","loc":[-85.632349,41.942699]},"n2123":{"id":"n2123","loc":[-85.628418,41.940356]},"n2124":{"id":"n2124","loc":[-85.629147,41.94129]},"n2125":{"id":"n2125","loc":[-85.631111,41.943979]},"n2126":{"id":"n2126","loc":[-85.632087,41.940013]},"n2127":{"id":"n2127","loc":[-85.634469,41.935057]},"n2128":{"id":"n2128","loc":[-85.630097,41.943449]},"n2129":{"id":"n2129","loc":[-85.6331,41.937878]},"n213":{"id":"n213","loc":[-85.63375,41.942814]},"n2130":{"id":"n2130","loc":[-85.625274,41.941114]},"n2131":{"id":"n2131","loc":[-85.632632,41.941217]},"n2132":{"id":"n2132","loc":[-85.632739,41.941926]},"n2133":{"id":"n2133","loc":[-85.631647,41.94366]},"n2134":{"id":"n2134","loc":[-85.635059,41.935456]},"n2135":{"id":"n2135","loc":[-85.631259,41.944349]},"n2136":{"id":"n2136","loc":[-85.626336,41.940811]},"n2137":{"id":"n2137","loc":[-85.631507,41.943875]},"n2138":{"id":"n2138","loc":[-85.625081,41.940859]},"n2139":{"id":"n2139","loc":[-85.625778,41.940093]},"n214":{"id":"n214","loc":[-85.633674,41.942869]},"n2140":{"id":"n2140","loc":[-85.632641,41.942436]},"n2141":{"id":"n2141","loc":[-85.628825,41.941034]},"n2142":{"id":"n2142","loc":[-85.627913,41.940292]},"n2143":{"id":"n2143","loc":[-85.628943,41.940516]},"n2144":{"id":"n2144","loc":[-85.63139,41.943941]},"n2145":{"id":"n2145","loc":[-85.630081,41.94204]},"n2146":{"id":"n2146","loc":[-85.632194,41.93963]},"n2147":{"id":"n2147","loc":[-85.632913,41.93939]},"n2148":{"id":"n2148","loc":[-85.632001,41.943492]},"n2149":{"id":"n2149","loc":[-85.63149,41.943154]},"n215":{"id":"n215","loc":[-85.633542,41.942768]},"n2150":{"id":"n2150","loc":[-85.625167,41.940117]},"n2151":{"id":"n2151","loc":[-85.63287,41.939941]},"n2152":{"id":"n2152","loc":[-85.630789,41.943732]},"n2153":{"id":"n2153","loc":[-85.632173,41.940348]},"n2154":{"id":"n2154","loc":[-85.626587,41.940113]},"n2155":{"id":"n2155","loc":[-85.62684,41.940667]},"n2156":{"id":"n2156","loc":[-85.632527,41.938904]},"n2157":{"id":"n2157","loc":[-85.624866,41.94018]},"n2158":{"id":"n2158","loc":[-85.633267,41.93872]},"n2159":{"id":"n2159","loc":[-85.62934,41.940843]},"n216":{"id":"n216","loc":[-85.633618,41.942714]},"n2160":{"id":"n2160","loc":[-85.62272,41.953817]},"n2161":{"id":"n2161","loc":[-85.622555,41.954453]},"n2162":{"id":"n2162","loc":[-85.637225,41.944128]},"n2163":{"id":"n2163","loc":[-85.622628,41.953683]},"n2164":{"id":"n2164","loc":[-85.635441,41.943989]},"n2165":{"id":"n2165","loc":[-85.622629,41.953807]},"n2166":{"id":"n2166","loc":[-85.62262,41.953807]},"n2167":{"id":"n2167","loc":[-85.62262,41.953837]},"n2168":{"id":"n2168","loc":[-85.622532,41.953838]},"n2169":{"id":"n2169","loc":[-85.637469,41.944579]},"n217":{"id":"n217","loc":[-85.634001,41.942336]},"n2170":{"id":"n2170","loc":[-85.63688,41.943935]},"n2171":{"id":"n2171","loc":[-85.638263,41.946367]},"n2172":{"id":"n2172","loc":[-85.622532,41.953807]},"n2173":{"id":"n2173","loc":[-85.622353,41.953808]},"n2174":{"id":"n2174","loc":[-85.622352,41.953685]},"n2175":{"id":"n2175","loc":[-85.622464,41.953684]},"n2176":{"id":"n2176","loc":[-85.622464,41.953648]},"n2177":{"id":"n2177","loc":[-85.637136,41.94576]},"n2178":{"id":"n2178","loc":[-85.622521,41.953648]},"n2179":{"id":"n2179","loc":[-85.637129,41.945415]},"n218":{"id":"n218","loc":[-85.633825,41.942376]},"n2180":{"id":"n2180","loc":[-85.637473,41.94607]},"n2181":{"id":"n2181","loc":[-85.622521,41.953683]},"n2182":{"id":"n2182","loc":[-85.622717,41.954104]},"n2183":{"id":"n2183","loc":[-85.637769,41.946095]},"n2184":{"id":"n2184","loc":[-85.623872,41.953515]},"n2185":{"id":"n2185","loc":[-85.623851,41.953588]},"n2186":{"id":"n2186","loc":[-85.631385,41.94433]},"n2187":{"id":"n2187","loc":[-85.623608,41.953543]},"n2188":{"id":"n2188","loc":[-85.637308,41.944882]},"n2189":{"id":"n2189","loc":[-85.634898,41.944041]},"n219":{"id":"n219","loc":[-85.633807,41.942334]},"n2190":{"id":"n2190","loc":[-85.623604,41.953442]},"n2191":{"id":"n2191","loc":[-85.623705,41.953442]},"n2192":{"id":"n2192","loc":[-85.623708,41.953493]},"n2193":{"id":"n2193","loc":[-85.624064,41.952655]},"n2194":{"id":"n2194","loc":[-85.62395,41.952654]},"n2195":{"id":"n2195","loc":[-85.623951,41.952579]},"n2196":{"id":"n2196","loc":[-85.637435,41.944342]},"n2197":{"id":"n2197","loc":[-85.624064,41.952579]},"n2198":{"id":"n2198","loc":[-85.623812,41.952648]},"n2199":{"id":"n2199","loc":[-85.623813,41.952705]},"n22":{"id":"n22","loc":[-85.633531,41.942357]},"n220":{"id":"n220","loc":[-85.633983,41.942294]},"n2200":{"id":"n2200","loc":[-85.637169,41.945098]},"n2201":{"id":"n2201","loc":[-85.623552,41.952707]},"n2202":{"id":"n2202","loc":[-85.623551,41.95263]},"n2203":{"id":"n2203","loc":[-85.623701,41.952629]},"n2204":{"id":"n2204","loc":[-85.635894,41.943719]},"n2205":{"id":"n2205","loc":[-85.637297,41.945992]},"n2206":{"id":"n2206","loc":[-85.623724,41.952648]},"n2207":{"id":"n2207","loc":[-85.623812,41.952438]},"n2208":{"id":"n2208","loc":[-85.625239,41.952197]},"n2209":{"id":"n2209","loc":[-85.625232,41.952257]},"n221":{"id":"n221","loc":[-85.634182,41.942495]},"n2210":{"id":"n2210","loc":[-85.635175,41.94408]},"n2211":{"id":"n2211","loc":[-85.636381,41.943761]},"n2212":{"id":"n2212","loc":[-85.625115,41.952249]},"n2213":{"id":"n2213","loc":[-85.638578,41.946644]},"n2214":{"id":"n2214","loc":[-85.625122,41.952189]},"n2215":{"id":"n2215","loc":[-85.625085,41.952031]},"n2216":{"id":"n2216","loc":[-85.636126,41.943713]},"n2217":{"id":"n2217","loc":[-85.635005,41.944041]},"n2218":{"id":"n2218","loc":[-85.63714,41.945328]},"n2219":{"id":"n2219","loc":[-85.634871,41.943292]},"n222":{"id":"n222","loc":[-85.634149,41.942503]},"n2220":{"id":"n2220","loc":[-85.635705,41.943799]},"n2221":{"id":"n2221","loc":[-85.634995,41.943576]},"n2222":{"id":"n2222","loc":[-85.635026,41.943829]},"n2223":{"id":"n2223","loc":[-85.632874,41.941031]},"n2224":{"id":"n2224","loc":[-85.632531,41.940233]},"n2225":{"id":"n2225","loc":[-85.634247,41.936003]},"n2226":{"id":"n2226","loc":[-85.62929,41.941127]},"n2227":{"id":"n2227","loc":[-85.630428,41.943266]},"n2228":{"id":"n2228","loc":[-85.631608,41.943425]},"n2229":{"id":"n2229","loc":[-85.632316,41.943042]},"n223":{"id":"n223","loc":[-85.634098,41.942373]},"n2230":{"id":"n2230","loc":[-85.628711,41.940744]},"n2231":{"id":"n2231","loc":[-85.627831,41.940536]},"n2232":{"id":"n2232","loc":[-85.625514,41.94052]},"n2233":{"id":"n2233","loc":[-85.631127,41.943545]},"n2234":{"id":"n2234","loc":[-85.632909,41.942531]},"n2235":{"id":"n2235","loc":[-85.632917,41.938796]},"n2236":{"id":"n2236","loc":[-85.626716,41.94044]},"n2237":{"id":"n2237","loc":[-85.630122,41.942852]},"n2238":{"id":"n2238","loc":[-85.632509,41.939674]},"n2239":{"id":"n2239","loc":[-85.634762,41.935237]},"n224":{"id":"n224","loc":[-85.634131,41.942366]},"n2240":{"id":"n2240","loc":[-85.63384,41.937025]},"n2241":{"id":"n2241","loc":[-85.629741,41.941909]},"n2242":{"id":"n2242","loc":[-85.635254,41.945001],"tags":{"railway":"level_crossing"}},"n2243":{"id":"n2243","loc":[-85.634005,41.938168]},"n2244":{"id":"n2244","loc":[-85.63393,41.938335]},"n2245":{"id":"n2245","loc":[-85.633859,41.93846]},"n2246":{"id":"n2246","loc":[-85.633663,41.938776]},"n2247":{"id":"n2247","loc":[-85.633513,41.938936]},"n2248":{"id":"n2248","loc":[-85.635295,41.943225]},"n2249":{"id":"n2249","loc":[-85.635393,41.943293]},"n225":{"id":"n225","loc":[-85.635986,41.94177]},"n2250":{"id":"n2250","loc":[-85.635645,41.94332]},"n2251":{"id":"n2251","loc":[-85.63629,41.943328]},"n2252":{"id":"n2252","loc":[-85.636554,41.943372]},"n2253":{"id":"n2253","loc":[-85.636869,41.943526]},"n2254":{"id":"n2254","loc":[-85.637099,41.943704]},"n2255":{"id":"n2255","loc":[-85.637268,41.943773]},"n2256":{"id":"n2256","loc":[-85.637483,41.943821]},"n2257":{"id":"n2257","loc":[-85.637616,41.943929]},"n2258":{"id":"n2258","loc":[-85.637752,41.944114]},"n2259":{"id":"n2259","loc":[-85.638399,41.944308]},"n226":{"id":"n226","loc":[-85.635982,41.941523]},"n2260":{"id":"n2260","loc":[-85.638573,41.944451]},"n2261":{"id":"n2261","loc":[-85.638702,41.944574]},"n2262":{"id":"n2262","loc":[-85.638718,41.944652]},"n2263":{"id":"n2263","loc":[-85.638715,41.944809]},"n2264":{"id":"n2264","loc":[-85.638766,41.944988]},"n2265":{"id":"n2265","loc":[-85.638773,41.945136]},"n2266":{"id":"n2266","loc":[-85.638705,41.945251]},"n2267":{"id":"n2267","loc":[-85.638335,41.944291]},"n2268":{"id":"n2268","loc":[-85.638474,41.944352]},"n2269":{"id":"n2269","loc":[-85.635408,41.943429]},"n227":{"id":"n227","loc":[-85.636108,41.941521]},"n2270":{"id":"n2270","loc":[-85.635271,41.943654]},"n2271":{"id":"n2271","loc":[-85.635266,41.943744]},"n2272":{"id":"n2272","loc":[-85.635271,41.943819]},"n2273":{"id":"n2273","loc":[-85.635192,41.943876]},"n2274":{"id":"n2274","loc":[-85.635129,41.943857]},"n2275":{"id":"n2275","loc":[-85.635122,41.943764]},"n2276":{"id":"n2276","loc":[-85.635124,41.943664]},"n2277":{"id":"n2277","loc":[-85.63515,41.943611]},"n2278":{"id":"n2278","loc":[-85.635106,41.943534]},"n2279":{"id":"n2279","loc":[-85.634972,41.943197]},"n228":{"id":"n228","loc":[-85.636109,41.941559]},"n2280":{"id":"n2280","loc":[-85.633978,41.938227]},"n2281":{"id":"n2281","loc":[-85.634216,41.943255]},"n2282":{"id":"n2282","loc":[-85.634434,41.943622]},"n2283":{"id":"n2283","loc":[-85.632406,41.940854]},"n2284":{"id":"n2284","loc":[-85.632488,41.941063],"tags":{"leisure":"slipway"}},"n2285":{"id":"n2285","loc":[-85.632726,41.941537]},"n2286":{"id":"n2286","loc":[-85.632639,41.94136]},"n2287":{"id":"n2287","loc":[-85.632704,41.941439]},"n2288":{"id":"n2288","loc":[-85.632289,41.940601]},"n2289":{"id":"n2289","loc":[-85.632541,41.942526]},"n229":{"id":"n229","loc":[-85.636145,41.941559]},"n2290":{"id":"n2290","loc":[-85.634058,41.943173]},"n2291":{"id":"n2291","loc":[-85.636175,41.945974]},"n2292":{"id":"n2292","loc":[-85.636528,41.945975]},"n2293":{"id":"n2293","loc":[-85.637092,41.945893]},"n2294":{"id":"n2294","loc":[-85.637881,41.945647]},"n2295":{"id":"n2295","loc":[-85.639329,41.945162]},"n2296":{"id":"n2296","loc":[-85.639323,41.945026]},"n2297":{"id":"n2297","loc":[-85.638826,41.945032]},"n2298":{"id":"n2298","loc":[-85.638817,41.944174]},"n2299":{"id":"n2299","loc":[-85.638291,41.94418]},"n23":{"id":"n23","loc":[-85.633504,41.942418]},"n230":{"id":"n230","loc":[-85.636145,41.941551]},"n2300":{"id":"n2300","loc":[-85.63828,41.943811]},"n2301":{"id":"n2301","loc":[-85.638195,41.943601]},"n2302":{"id":"n2302","loc":[-85.63719,41.943592]},"n2303":{"id":"n2303","loc":[-85.636697,41.943273]},"n2304":{"id":"n2304","loc":[-85.635375,41.943274]},"n2305":{"id":"n2305","loc":[-85.635091,41.943547]},"n2306":{"id":"n2306","loc":[-85.63442,41.944117]},"n2307":{"id":"n2307","loc":[-85.635117,41.943717]},"n2308":{"id":"n2308","loc":[-85.635601,41.945177]},"n2309":{"id":"n2309","loc":[-85.635819,41.945494]},"n231":{"id":"n231","loc":[-85.636312,41.941549]},"n2310":{"id":"n2310","loc":[-85.635303,41.944891]},"n2311":{"id":"n2311","loc":[-85.637674,41.943802]},"n2312":{"id":"n2312","loc":[-85.638263,41.944272]},"n2313":{"id":"n2313","loc":[-85.634267,41.935266]},"n2314":{"id":"n2314","loc":[-85.639788,41.945152]},"n2315":{"id":"n2315","loc":[-85.639645,41.945167]},"n2316":{"id":"n2316","loc":[-85.639362,41.945233]},"n2317":{"id":"n2317","loc":[-85.638616,41.945163]},"n2318":{"id":"n2318","loc":[-85.638514,41.944936]},"n2319":{"id":"n2319","loc":[-85.638578,41.94503]},"n232":{"id":"n232","loc":[-85.636314,41.941649]},"n2320":{"id":"n2320","loc":[-85.638578,41.945215]},"n2321":{"id":"n2321","loc":[-85.640495,41.947015]},"n2322":{"id":"n2322","loc":[-85.639577,41.946495]},"n2323":{"id":"n2323","loc":[-85.638935,41.946087]},"n2324":{"id":"n2324","loc":[-85.637535,41.94584]},"n2325":{"id":"n2325","loc":[-85.638357,41.945404]},"n2326":{"id":"n2326","loc":[-85.638051,41.94553]},"n2327":{"id":"n2327","loc":[-85.637732,41.945555]},"n2328":{"id":"n2328","loc":[-85.637657,41.945524]},"n2329":{"id":"n2329","loc":[-85.637598,41.945467]},"n233":{"id":"n233","loc":[-85.636152,41.94165]},"n2330":{"id":"n2330","loc":[-85.637669,41.945318]},"n2331":{"id":"n2331","loc":[-85.637894,41.945171]},"n2332":{"id":"n2332","loc":[-85.637923,41.945082]},"n2333":{"id":"n2333","loc":[-85.63793,41.944756]},"n2334":{"id":"n2334","loc":[-85.637976,41.944696]},"n2335":{"id":"n2335","loc":[-85.638044,41.944671]},"n2336":{"id":"n2336","loc":[-85.638129,41.944597]},"n2337":{"id":"n2337","loc":[-85.638252,41.944413]},"n2338":{"id":"n2338","loc":[-85.638092,41.945442]},"n2339":{"id":"n2339","loc":[-85.638409,41.945315]},"n234":{"id":"n234","loc":[-85.636152,41.941628]},"n2340":{"id":"n2340","loc":[-85.638325,41.944771]},"n2341":{"id":"n2341","loc":[-85.638103,41.944744]},"n2342":{"id":"n2342","loc":[-85.637976,41.944781]},"n2343":{"id":"n2343","loc":[-85.637983,41.944865]},"n2344":{"id":"n2344","loc":[-85.638063,41.945074]},"n2345":{"id":"n2345","loc":[-85.638041,41.945206]},"n2346":{"id":"n2346","loc":[-85.637907,41.945309]},"n2347":{"id":"n2347","loc":[-85.637925,41.94539]},"n2348":{"id":"n2348","loc":[-85.637998,41.94545]},"n2349":{"id":"n2349","loc":[-85.637135,41.946254]},"n235":{"id":"n235","loc":[-85.63611,41.941628]},"n2350":{"id":"n2350","loc":[-85.636837,41.946615]},"n2351":{"id":"n2351","loc":[-85.637954,41.948909]},"n2352":{"id":"n2352","loc":[-85.638382,41.949786]},"n2353":{"id":"n2353","loc":[-85.639367,41.951242]},"n2354":{"id":"n2354","loc":[-85.640554,41.951777]},"n2355":{"id":"n2355","loc":[-85.6411,41.952234]},"n2356":{"id":"n2356","loc":[-85.641742,41.952657]},"n2357":{"id":"n2357","loc":[-85.642321,41.952941]},"n2358":{"id":"n2358","loc":[-85.64277,41.953228]},"n2359":{"id":"n2359","loc":[-85.643333,41.953825]},"n236":{"id":"n236","loc":[-85.636113,41.941768]},"n2360":{"id":"n2360","loc":[-85.643579,41.954365]},"n2361":{"id":"n2361","loc":[-85.644439,41.954105]},"n2362":{"id":"n2362","loc":[-85.64506,41.954]},"n2363":{"id":"n2363","loc":[-85.645483,41.953911]},"n2364":{"id":"n2364","loc":[-85.646046,41.953853]},"n2365":{"id":"n2365","loc":[-85.646318,41.953717]},"n2366":{"id":"n2366","loc":[-85.646276,41.953414]},"n2367":{"id":"n2367","loc":[-85.631063,41.957478],"tags":{"emergency":"fire_hydrant"}},"n2368":{"id":"n2368","loc":[-85.630996,41.955857],"tags":{"emergency":"fire_hydrant"}},"n2369":{"id":"n2369","loc":[-85.630976,41.954608],"tags":{"emergency":"fire_hydrant"}},"n237":{"id":"n237","loc":[-85.635983,41.941589],"tags":{"entrance":"yes"}},"n2370":{"id":"n2370","loc":[-85.646,41.953154]},"n2371":{"id":"n2371","loc":[-85.645222,41.953193]},"n2372":{"id":"n2372","loc":[-85.644732,41.953181]},"n2373":{"id":"n2373","loc":[-85.644064,41.953298]},"n2374":{"id":"n2374","loc":[-85.643818,41.953177]},"n2375":{"id":"n2375","loc":[-85.644001,41.95284]},"n2376":{"id":"n2376","loc":[-85.628174,41.95456],"tags":{"emergency":"fire_hydrant"}},"n2377":{"id":"n2377","loc":[-85.644267,41.952591]},"n2378":{"id":"n2378","loc":[-85.644288,41.952328]},"n2379":{"id":"n2379","loc":[-85.627276,41.953987],"tags":{"emergency":"fire_hydrant"}},"n238":{"id":"n238","loc":[-85.635906,41.94159]},"n2380":{"id":"n2380","loc":[-85.644262,41.952153]},"n2381":{"id":"n2381","loc":[-85.644168,41.95204]},"n2382":{"id":"n2382","loc":[-85.64421,41.951749]},"n2383":{"id":"n2383","loc":[-85.64385,41.951586]},"n2384":{"id":"n2384","loc":[-85.62736,41.955964],"tags":{"emergency":"fire_hydrant"}},"n2385":{"id":"n2385","loc":[-85.626307,41.957198],"tags":{"emergency":"fire_hydrant"}},"n2386":{"id":"n2386","loc":[-85.643589,41.951323]},"n2387":{"id":"n2387","loc":[-85.62747,41.957509],"tags":{"emergency":"fire_hydrant"}},"n2388":{"id":"n2388","loc":[-85.628665,41.957492],"tags":{"emergency":"fire_hydrant"}},"n2389":{"id":"n2389","loc":[-85.642535,41.951031]},"n239":{"id":"n239","loc":[-85.635883,41.940182]},"n2390":{"id":"n2390","loc":[-85.642269,41.95088]},"n2391":{"id":"n2391","loc":[-85.641878,41.950814]},"n2392":{"id":"n2392","loc":[-85.641549,41.950806]},"n2393":{"id":"n2393","loc":[-85.641103,41.950549]},"n2394":{"id":"n2394","loc":[-85.630864,41.959046],"tags":{"emergency":"fire_hydrant"}},"n2395":{"id":"n2395","loc":[-85.632249,41.958969],"tags":{"emergency":"fire_hydrant"}},"n2396":{"id":"n2396","loc":[-85.641037,41.949821]},"n2397":{"id":"n2397","loc":[-85.641006,41.949433]},"n2398":{"id":"n2398","loc":[-85.632232,41.95859],"tags":{"emergency":"fire_hydrant"}},"n2399":{"id":"n2399","loc":[-85.632071,41.958345],"tags":{"emergency":"fire_hydrant"}},"n24":{"id":"n24","loc":[-85.634346,41.942792]},"n240":{"id":"n240","loc":[-85.635916,41.94264]},"n2400":{"id":"n2400","loc":[-85.632228,41.9573],"tags":{"emergency":"fire_hydrant"}},"n2401":{"id":"n2401","loc":[-85.641152,41.948257]},"n2402":{"id":"n2402","loc":[-85.641055,41.947304]},"n2403":{"id":"n2403","loc":[-85.638022,41.945897]},"n2404":{"id":"n2404","loc":[-85.638672,41.950778]},"n2405":{"id":"n2405","loc":[-85.63666,41.944492],"tags":{"name":"Memory Isle","place":"island"}},"n2406":{"id":"n2406","loc":[-85.635,41.946389],"tags":{"amenity":"post_office","name":"Three Rivers Post Office"}},"n2407":{"id":"n2407","loc":[-85.633676,41.946036]},"n2408":{"id":"n2408","loc":[-85.633736,41.946078]},"n2409":{"id":"n2409","loc":[-85.633997,41.946185]},"n241":{"id":"n241","loc":[-85.635795,41.941906]},"n2410":{"id":"n2410","loc":[-85.634448,41.945626],"tags":{"highway":"traffic_signals","traffic_signals":"signal"}},"n2411":{"id":"n2411","loc":[-85.63456,41.945731],"tags":{"crossing":"zebra","highway":"crossing"}},"n2412":{"id":"n2412","loc":[-85.634592,41.94578]},"n2413":{"id":"n2413","loc":[-85.634607,41.945815]},"n2414":{"id":"n2414","loc":[-85.634614,41.945864]},"n2415":{"id":"n2415","loc":[-85.636066,41.946185]},"n2416":{"id":"n2416","loc":[-85.636128,41.946352]},"n2417":{"id":"n2417","loc":[-85.636142,41.946452]},"n2418":{"id":"n2418","loc":[-85.635327,41.945292]},"n2419":{"id":"n2419","loc":[-85.635648,41.94558]},"n242":{"id":"n242","loc":[-85.635909,41.941906]},"n2420":{"id":"n2420","loc":[-85.635769,41.945729]},"n2421":{"id":"n2421","loc":[-85.637349,41.945897]},"n2422":{"id":"n2422","loc":[-85.632211,41.95596],"tags":{"emergency":"fire_hydrant"}},"n2423":{"id":"n2423","loc":[-85.635942,41.94598]},"n2424":{"id":"n2424","loc":[-85.636443,41.946042]},"n2425":{"id":"n2425","loc":[-85.635819,41.946052]},"n2426":{"id":"n2426","loc":[-85.636669,41.946025]},"n2427":{"id":"n2427","loc":[-85.636832,41.946005]},"n2428":{"id":"n2428","loc":[-85.637039,41.945968]},"n2429":{"id":"n2429","loc":[-85.636291,41.946046]},"n243":{"id":"n243","loc":[-85.636359,41.941904]},"n2430":{"id":"n2430","loc":[-85.634005,41.943367]},"n2431":{"id":"n2431","loc":[-85.633366,41.943724]},"n2432":{"id":"n2432","loc":[-85.634617,41.946057]},"n2433":{"id":"n2433","loc":[-85.636534,41.944793]},"n2434":{"id":"n2434","loc":[-85.637055,41.945188]},"n2435":{"id":"n2435","loc":[-85.636153,41.944618]},"n2436":{"id":"n2436","loc":[-85.636803,41.944944]},"n2437":{"id":"n2437","loc":[-85.633389,41.945735]},"n2438":{"id":"n2438","loc":[-85.633536,41.94585]},"n2439":{"id":"n2439","loc":[-85.63363,41.945993]},"n244":{"id":"n244","loc":[-85.636351,41.941438]},"n2440":{"id":"n2440","loc":[-85.633268,41.94568]},"n2441":{"id":"n2441","loc":[-85.635947,41.94546]},"n2442":{"id":"n2442","loc":[-85.636277,41.945268]},"n2443":{"id":"n2443","loc":[-85.635203,41.944287]},"n2444":{"id":"n2444","loc":[-85.634876,41.944477]},"n2445":{"id":"n2445","loc":[-85.634975,41.944419]},"n2446":{"id":"n2446","loc":[-85.633877,41.943438]},"n2447":{"id":"n2447","loc":[-85.63508,41.945113]},"n2448":{"id":"n2448","loc":[-85.635372,41.944932]},"n2449":{"id":"n2449","loc":[-85.636594,41.945935]},"n245":{"id":"n245","loc":[-85.635903,41.941436]},"n2450":{"id":"n2450","loc":[-85.636901,41.945747]},"n2451":{"id":"n2451","loc":[-85.636329,41.945228]},"n2452":{"id":"n2452","loc":[-85.636025,41.945417]},"n2453":{"id":"n2453","loc":[-85.634002,41.944644]},"n2454":{"id":"n2454","loc":[-85.63407,41.944692]},"n2455":{"id":"n2455","loc":[-85.634114,41.944756]},"n2456":{"id":"n2456","loc":[-85.633762,41.944809]},"n2457":{"id":"n2457","loc":[-85.634184,41.944807]},"n2458":{"id":"n2458","loc":[-85.634291,41.944819]},"n2459":{"id":"n2459","loc":[-85.634639,41.944845]},"n246":{"id":"n246","loc":[-85.635788,41.941436]},"n2460":{"id":"n2460","loc":[-85.633822,41.944861]},"n2461":{"id":"n2461","loc":[-85.63411,41.944855]},"n2462":{"id":"n2462","loc":[-85.63435,41.944872]},"n2463":{"id":"n2463","loc":[-85.63441,41.944903]},"n2464":{"id":"n2464","loc":[-85.633883,41.944913]},"n2465":{"id":"n2465","loc":[-85.634164,41.944896]},"n2466":{"id":"n2466","loc":[-85.633487,41.944926]},"n2467":{"id":"n2467","loc":[-85.634736,41.944929]},"n2468":{"id":"n2468","loc":[-85.633944,41.944965]},"n2469":{"id":"n2469","loc":[-85.633555,41.944983]},"n247":{"id":"n247","loc":[-85.635929,41.941511]},"n2470":{"id":"n2470","loc":[-85.633995,41.945013]},"n2471":{"id":"n2471","loc":[-85.633614,41.945037]},"n2472":{"id":"n2472","loc":[-85.634848,41.945031]},"n2473":{"id":"n2473","loc":[-85.634049,41.945061]},"n2474":{"id":"n2474","loc":[-85.633678,41.945094]},"n2475":{"id":"n2475","loc":[-85.63317,41.945111]},"n2476":{"id":"n2476","loc":[-85.633357,41.945103]},"n2477":{"id":"n2477","loc":[-85.633728,41.945136]},"n2478":{"id":"n2478","loc":[-85.634146,41.945148]},"n2479":{"id":"n2479","loc":[-85.633416,41.945157]},"n248":{"id":"n248","loc":[-85.635929,41.941317]},"n2480":{"id":"n2480","loc":[-85.634625,41.945172]},"n2481":{"id":"n2481","loc":[-85.633239,41.945174]},"n2482":{"id":"n2482","loc":[-85.63469,41.945185]},"n2483":{"id":"n2483","loc":[-85.634661,41.945203]},"n2484":{"id":"n2484","loc":[-85.63348,41.945214]},"n2485":{"id":"n2485","loc":[-85.633578,41.945221]},"n2486":{"id":"n2486","loc":[-85.634742,41.945231]},"n2487":{"id":"n2487","loc":[-85.634251,41.94525]},"n2488":{"id":"n2488","loc":[-85.633524,41.945254]},"n2489":{"id":"n2489","loc":[-85.63468,41.945271]},"n249":{"id":"n249","loc":[-85.636414,41.941316]},"n2490":{"id":"n2490","loc":[-85.633885,41.945272]},"n2491":{"id":"n2491","loc":[-85.634795,41.945288]},"n2492":{"id":"n2492","loc":[-85.634742,41.94532]},"n2493":{"id":"n2493","loc":[-85.633946,41.945327]},"n2494":{"id":"n2494","loc":[-85.634844,41.945331]},"n2495":{"id":"n2495","loc":[-85.63435,41.945349]},"n2496":{"id":"n2496","loc":[-85.633733,41.945357]},"n2497":{"id":"n2497","loc":[-85.633987,41.945375]},"n2498":{"id":"n2498","loc":[-85.634911,41.945419]},"n2499":{"id":"n2499","loc":[-85.634049,41.945431]},"n25":{"id":"n25","loc":[-85.634333,41.942809]},"n250":{"id":"n250","loc":[-85.636414,41.941511]},"n2500":{"id":"n2500","loc":[-85.633705,41.945461]},"n2501":{"id":"n2501","loc":[-85.633642,41.945408]},"n2502":{"id":"n2502","loc":[-85.634493,41.945475]},"n2503":{"id":"n2503","loc":[-85.634106,41.945484]},"n2504":{"id":"n2504","loc":[-85.635008,41.945505]},"n2505":{"id":"n2505","loc":[-85.633757,41.945506]},"n2506":{"id":"n2506","loc":[-85.634542,41.945519]},"n2507":{"id":"n2507","loc":[-85.634162,41.945536]},"n2508":{"id":"n2508","loc":[-85.633843,41.945547]},"n2509":{"id":"n2509","loc":[-85.634919,41.94556]},"n251":{"id":"n251","loc":[-85.636819,41.941617]},"n2510":{"id":"n2510","loc":[-85.633818,41.945561]},"n2511":{"id":"n2511","loc":[-85.634638,41.94559]},"n2512":{"id":"n2512","loc":[-85.633901,41.945598]},"n2513":{"id":"n2513","loc":[-85.634257,41.945626]},"n2514":{"id":"n2514","loc":[-85.633967,41.945652]},"n2515":{"id":"n2515","loc":[-85.634735,41.945676]},"n2516":{"id":"n2516","loc":[-85.635057,41.945683]},"n2517":{"id":"n2517","loc":[-85.635296,41.945703]},"n2518":{"id":"n2518","loc":[-85.635112,41.945703]},"n2519":{"id":"n2519","loc":[-85.634782,41.945729]},"n252":{"id":"n252","loc":[-85.636718,41.941619]},"n2520":{"id":"n2520","loc":[-85.634052,41.945747]},"n2521":{"id":"n2521","loc":[-85.635296,41.945757]},"n2522":{"id":"n2522","loc":[-85.635314,41.945757]},"n2523":{"id":"n2523","loc":[-85.635112,41.945761]},"n2524":{"id":"n2524","loc":[-85.63484,41.945778]},"n2525":{"id":"n2525","loc":[-85.635314,41.945938]},"n2526":{"id":"n2526","loc":[-85.63484,41.945922]},"n2527":{"id":"n2527","loc":[-85.635461,41.944879]},"n2528":{"id":"n2528","loc":[-85.636024,41.945384]},"n2529":{"id":"n2529","loc":[-85.636145,41.945312]},"n253":{"id":"n253","loc":[-85.636716,41.941509]},"n2530":{"id":"n2530","loc":[-85.6356,41.944797]},"n2531":{"id":"n2531","loc":[-85.635135,41.944354]},"n2532":{"id":"n2532","loc":[-85.632988,41.945369]},"n2533":{"id":"n2533","loc":[-85.633376,41.94563]},"n2534":{"id":"n2534","loc":[-85.633539,41.945534]},"n2535":{"id":"n2535","loc":[-85.633238,41.945248]},"n2536":{"id":"n2536","loc":[-85.633166,41.945216]},"n2537":{"id":"n2537","loc":[-85.633114,41.945188]},"n2538":{"id":"n2538","loc":[-85.633078,41.945127]},"n2539":{"id":"n2539","loc":[-85.633066,41.94508]},"n254":{"id":"n254","loc":[-85.636732,41.941509]},"n2540":{"id":"n2540","loc":[-85.633222,41.945358]},"n2541":{"id":"n2541","loc":[-85.633425,41.945541]},"n2542":{"id":"n2542","loc":[-85.63299,41.9455]},"n2543":{"id":"n2543","loc":[-85.634374,41.944327]},"n2544":{"id":"n2544","loc":[-85.633648,41.943697]},"n2545":{"id":"n2545","loc":[-85.633533,41.943764]},"n2546":{"id":"n2546","loc":[-85.634239,41.944417]},"n2547":{"id":"n2547","loc":[-85.634122,41.944395]},"n2548":{"id":"n2548","loc":[-85.634235,41.944326]},"n2549":{"id":"n2549","loc":[-85.633613,41.943787]},"n255":{"id":"n255","loc":[-85.636731,41.941461]},"n2550":{"id":"n2550","loc":[-85.633915,41.943613]},"n2551":{"id":"n2551","loc":[-85.634015,41.943555]},"n2552":{"id":"n2552","loc":[-85.63433,41.943839]},"n2553":{"id":"n2553","loc":[-85.634236,41.943894]},"n2554":{"id":"n2554","loc":[-85.635413,41.946052]},"n2555":{"id":"n2555","loc":[-85.635405,41.94569]},"n2556":{"id":"n2556","loc":[-85.635684,41.945925]},"n2557":{"id":"n2557","loc":[-85.635614,41.945742]},"n2558":{"id":"n2558","loc":[-85.635401,41.945745]},"n2559":{"id":"n2559","loc":[-85.635406,41.945928]},"n256":{"id":"n256","loc":[-85.636799,41.941461]},"n2560":{"id":"n2560","loc":[-85.633478,41.943663]},"n2561":{"id":"n2561","loc":[-85.633291,41.943526]},"n2562":{"id":"n2562","loc":[-85.633094,41.943541]},"n2563":{"id":"n2563","loc":[-85.633302,41.943492]},"n2564":{"id":"n2564","loc":[-85.633047,41.943623]},"n2565":{"id":"n2565","loc":[-85.633275,41.943562]},"n2566":{"id":"n2566","loc":[-85.633351,41.943518]},"n2567":{"id":"n2567","loc":[-85.633224,41.9434]},"n2568":{"id":"n2568","loc":[-85.633235,41.943369]},"n2569":{"id":"n2569","loc":[-85.635179,41.943911]},"n257":{"id":"n257","loc":[-85.6368,41.9415]},"n2570":{"id":"n2570","loc":[-85.635146,41.943918]},"n2571":{"id":"n2571","loc":[-85.634888,41.943905]},"n2572":{"id":"n2572","loc":[-85.634832,41.943911]},"n2573":{"id":"n2573","loc":[-85.634638,41.944007]},"n2574":{"id":"n2574","loc":[-85.634568,41.94405]},"n2575":{"id":"n2575","loc":[-85.635994,41.94501]},"n2576":{"id":"n2576","loc":[-85.636388,41.944608]},"n2577":{"id":"n2577","loc":[-85.636215,41.944787]},"n2578":{"id":"n2578","loc":[-85.637948,41.944587]},"n2579":{"id":"n2579","loc":[-85.637849,41.944567]},"n258":{"id":"n258","loc":[-85.636814,41.9415]},"n2580":{"id":"n2580","loc":[-85.637895,41.944455]},"n2581":{"id":"n2581","loc":[-85.637996,41.944477]},"n2582":{"id":"n2582","loc":[-85.635525,41.94337]},"n2583":{"id":"n2583","loc":[-85.637847,41.943923]},"n2584":{"id":"n2584","loc":[-85.637891,41.944124]},"n2585":{"id":"n2585","loc":[-85.638167,41.944229]},"n2586":{"id":"n2586","loc":[-85.638236,41.944097]},"n2587":{"id":"n2587","loc":[-85.638207,41.944025]},"n2588":{"id":"n2588","loc":[-85.638141,41.943997]},"n2589":{"id":"n2589","loc":[-85.638057,41.944015]},"n259":{"id":"n259","loc":[-85.636815,41.941538]},"n2590":{"id":"n2590","loc":[-85.637902,41.944231]},"n2591":{"id":"n2591","loc":[-85.638134,41.944307]},"n2592":{"id":"n2592","loc":[-85.638242,41.944294]},"n2593":{"id":"n2593","loc":[-85.638274,41.944222]},"n2594":{"id":"n2594","loc":[-85.638236,41.944174]},"n2595":{"id":"n2595","loc":[-85.638207,41.944157]},"n2596":{"id":"n2596","loc":[-85.637818,41.943984]},"n2597":{"id":"n2597","loc":[-85.634996,41.944439]},"n2598":{"id":"n2598","loc":[-85.633946,41.945804]},"n2599":{"id":"n2599","loc":[-85.634102,41.945864]},"n26":{"id":"n26","loc":[-85.634346,41.942744]},"n260":{"id":"n260","loc":[-85.636827,41.941538]},"n2600":{"id":"n2600","loc":[-85.633819,41.945756]},"n2601":{"id":"n2601","loc":[-85.634025,41.945975]},"n2602":{"id":"n2602","loc":[-85.633742,41.945867]},"n2603":{"id":"n2603","loc":[-85.63373,41.946004]},"n2604":{"id":"n2604","loc":[-85.633947,41.946081]},"n2605":{"id":"n2605","loc":[-85.633872,41.945917]},"n2606":{"id":"n2606","loc":[-85.633825,41.945985]},"n2607":{"id":"n2607","loc":[-85.633762,41.94596]},"n2608":{"id":"n2608","loc":[-85.634224,41.946037]},"n2609":{"id":"n2609","loc":[-85.634357,41.945851]},"n261":{"id":"n261","loc":[-85.636828,41.941584]},"n2610":{"id":"n2610","loc":[-85.634398,41.945813]},"n2611":{"id":"n2611","loc":[-85.634461,41.945812]},"n2612":{"id":"n2612","loc":[-85.634501,41.945852]},"n2613":{"id":"n2613","loc":[-85.634503,41.94597]},"n2614":{"id":"n2614","loc":[-85.634462,41.945971]},"n2615":{"id":"n2615","loc":[-85.634465,41.946036]},"n2616":{"id":"n2616","loc":[-85.634235,41.946072]},"n2617":{"id":"n2617","loc":[-85.634447,41.946036]},"n2618":{"id":"n2618","loc":[-85.634448,41.946052]},"n2619":{"id":"n2619","loc":[-85.634494,41.946051]},"n262":{"id":"n262","loc":[-85.636819,41.941585]},"n2620":{"id":"n2620","loc":[-85.634497,41.946144]},"n2621":{"id":"n2621","loc":[-85.634453,41.946144]},"n2622":{"id":"n2622","loc":[-85.634454,41.94616]},"n2623":{"id":"n2623","loc":[-85.634393,41.946161]},"n2624":{"id":"n2624","loc":[-85.634394,41.94618]},"n2625":{"id":"n2625","loc":[-85.634345,41.94618]},"n2626":{"id":"n2626","loc":[-85.634344,41.946162]},"n2627":{"id":"n2627","loc":[-85.63427,41.946163]},"n2628":{"id":"n2628","loc":[-85.634266,41.946071]},"n2629":{"id":"n2629","loc":[-85.634148,41.946163]},"n263":{"id":"n263","loc":[-85.636854,41.941714]},"n2630":{"id":"n2630","loc":[-85.634213,41.946072]},"n2631":{"id":"n2631","loc":[-85.633293,41.946309]},"n2632":{"id":"n2632","loc":[-85.633122,41.946239]},"n2633":{"id":"n2633","loc":[-85.633295,41.946005]},"n2634":{"id":"n2634","loc":[-85.633395,41.946047]},"n2635":{"id":"n2635","loc":[-85.633404,41.946035]},"n2636":{"id":"n2636","loc":[-85.633459,41.946057]},"n2637":{"id":"n2637","loc":[-85.633387,41.946154]},"n2638":{"id":"n2638","loc":[-85.633403,41.946161]},"n2639":{"id":"n2639","loc":[-85.634176,41.946415]},"n264":{"id":"n264","loc":[-85.636855,41.941774]},"n2640":{"id":"n2640","loc":[-85.634179,41.946339]},"n2641":{"id":"n2641","loc":[-85.634455,41.946345]},"n2642":{"id":"n2642","loc":[-85.634452,41.946422]},"n2643":{"id":"n2643","loc":[-85.63437,41.946421]},"n2644":{"id":"n2644","loc":[-85.634367,41.946497]},"n2645":{"id":"n2645","loc":[-85.634289,41.946495]},"n2646":{"id":"n2646","loc":[-85.634291,41.946448]},"n2647":{"id":"n2647","loc":[-85.634269,41.946448]},"n2648":{"id":"n2648","loc":[-85.63427,41.946417]},"n2649":{"id":"n2649","loc":[-85.63484,41.946328]},"n265":{"id":"n265","loc":[-85.636822,41.941774]},"n2650":{"id":"n2650","loc":[-85.634839,41.946187]},"n2651":{"id":"n2651","loc":[-85.635148,41.946186]},"n2652":{"id":"n2652","loc":[-85.635148,41.946216]},"n2653":{"id":"n2653","loc":[-85.63521,41.946216]},"n2654":{"id":"n2654","loc":[-85.63521,41.946348]},"n2655":{"id":"n2655","loc":[-85.635154,41.946348]},"n2656":{"id":"n2656","loc":[-85.635153,41.946327]},"n2657":{"id":"n2657","loc":[-85.634037,41.946957]},"n2658":{"id":"n2658","loc":[-85.634253,41.946953]},"n2659":{"id":"n2659","loc":[-85.63481,41.946543]},"n266":{"id":"n266","loc":[-85.636822,41.941778]},"n2660":{"id":"n2660","loc":[-85.634809,41.946459]},"n2661":{"id":"n2661","loc":[-85.635154,41.946458]},"n2662":{"id":"n2662","loc":[-85.635155,41.946554]},"n2663":{"id":"n2663","loc":[-85.635022,41.946547]},"n2664":{"id":"n2664","loc":[-85.635022,41.946573]},"n2665":{"id":"n2665","loc":[-85.634909,41.946574]},"n2666":{"id":"n2666","loc":[-85.634909,41.946561]},"n2667":{"id":"n2667","loc":[-85.634896,41.947159]},"n2668":{"id":"n2668","loc":[-85.634894,41.947032]},"n2669":{"id":"n2669","loc":[-85.635024,41.947031]},"n267":{"id":"n267","loc":[-85.636756,41.941779]},"n2670":{"id":"n2670","loc":[-85.635026,41.947158]},"n2671":{"id":"n2671","loc":[-85.635233,41.947105]},"n2672":{"id":"n2672","loc":[-85.635236,41.946991]},"n2673":{"id":"n2673","loc":[-85.635369,41.946993]},"n2674":{"id":"n2674","loc":[-85.635366,41.947107]},"n2675":{"id":"n2675","loc":[-85.634824,41.946929]},"n2676":{"id":"n2676","loc":[-85.634825,41.946818]},"n2677":{"id":"n2677","loc":[-85.63512,41.946819]},"n2678":{"id":"n2678","loc":[-85.635119,41.94693]},"n2679":{"id":"n2679","loc":[-85.634796,41.946806]},"n268":{"id":"n268","loc":[-85.636756,41.941774]},"n2680":{"id":"n2680","loc":[-85.634792,41.946604]},"n2681":{"id":"n2681","loc":[-85.634948,41.946602]},"n2682":{"id":"n2682","loc":[-85.634949,41.946645]},"n2683":{"id":"n2683","loc":[-85.634975,41.946644]},"n2684":{"id":"n2684","loc":[-85.634974,41.946599]},"n2685":{"id":"n2685","loc":[-85.635117,41.946598]},"n2686":{"id":"n2686","loc":[-85.635122,41.946801]},"n2687":{"id":"n2687","loc":[-85.634981,41.946803]},"n2688":{"id":"n2688","loc":[-85.634979,41.946752]},"n2689":{"id":"n2689","loc":[-85.634952,41.946752]},"n269":{"id":"n269","loc":[-85.636721,41.941774]},"n2690":{"id":"n2690","loc":[-85.634953,41.946804]},"n2691":{"id":"n2691","loc":[-85.634649,41.946841]},"n2692":{"id":"n2692","loc":[-85.634331,41.94684]},"n2693":{"id":"n2693","loc":[-85.634183,41.946809]},"n2694":{"id":"n2694","loc":[-85.633699,41.946607]},"n2695":{"id":"n2695","loc":[-85.634487,41.946664]},"n2696":{"id":"n2696","loc":[-85.634486,41.946598]},"n2697":{"id":"n2697","loc":[-85.63423,41.946599]},"n2698":{"id":"n2698","loc":[-85.634231,41.946662]},"n2699":{"id":"n2699","loc":[-85.634284,41.946662]},"n27":{"id":"n27","loc":[-85.634136,41.943183]},"n270":{"id":"n270","loc":[-85.63672,41.941714]},"n2700":{"id":"n2700","loc":[-85.634284,41.946679]},"n2701":{"id":"n2701","loc":[-85.634365,41.946679]},"n2702":{"id":"n2702","loc":[-85.634365,41.946664]},"n2703":{"id":"n2703","loc":[-85.635443,41.947015]},"n2704":{"id":"n2704","loc":[-85.635442,41.946801]},"n2705":{"id":"n2705","loc":[-85.63603,41.9468]},"n2706":{"id":"n2706","loc":[-85.636028,41.947016]},"n2707":{"id":"n2707","loc":[-85.635457,41.946582]},"n2708":{"id":"n2708","loc":[-85.635455,41.946211]},"n2709":{"id":"n2709","loc":[-85.635636,41.946579]},"n271":{"id":"n271","loc":[-85.636767,41.941713]},"n2710":{"id":"n2710","loc":[-85.635716,41.9468]},"n2711":{"id":"n2711","loc":[-85.635969,41.9468]},"n2712":{"id":"n2712","loc":[-85.635973,41.946295]},"n2713":{"id":"n2713","loc":[-85.636019,41.946484]},"n2714":{"id":"n2714","loc":[-85.636022,41.946388]},"n2715":{"id":"n2715","loc":[-85.635961,41.946493]},"n2716":{"id":"n2716","loc":[-85.635713,41.94621]},"n2717":{"id":"n2717","loc":[-85.635416,41.946142]},"n2718":{"id":"n2718","loc":[-85.635759,41.946203]},"n2719":{"id":"n2719","loc":[-85.636153,41.946747]},"n272":{"id":"n272","loc":[-85.636767,41.941706]},"n2720":{"id":"n2720","loc":[-85.635417,41.946915]},"n2721":{"id":"n2721","loc":[-85.636154,41.946915]},"n2722":{"id":"n2722","loc":[-85.635866,41.946473]},"n2723":{"id":"n2723","loc":[-85.635717,41.946633]},"n2724":{"id":"n2724","loc":[-85.635556,41.946166]},"n2725":{"id":"n2725","loc":[-85.63556,41.946556]},"n2726":{"id":"n2726","loc":[-85.635731,41.946594]},"n2727":{"id":"n2727","loc":[-85.635866,41.946595]},"n2728":{"id":"n2728","loc":[-85.635456,41.947028]},"n2729":{"id":"n2729","loc":[-85.635796,41.947023]},"n273":{"id":"n273","loc":[-85.636779,41.941698]},"n2730":{"id":"n2730","loc":[-85.635798,41.947091]},"n2731":{"id":"n2731","loc":[-85.63573,41.947092]},"n2732":{"id":"n2732","loc":[-85.635733,41.947233]},"n2733":{"id":"n2733","loc":[-85.636283,41.946863]},"n2734":{"id":"n2734","loc":[-85.63628,41.946706]},"n2735":{"id":"n2735","loc":[-85.636341,41.946705]},"n2736":{"id":"n2736","loc":[-85.636273,41.946584]},"n2737":{"id":"n2737","loc":[-85.636396,41.946545]},"n2738":{"id":"n2738","loc":[-85.636474,41.946684]},"n2739":{"id":"n2739","loc":[-85.636511,41.946861]},"n274":{"id":"n274","loc":[-85.636798,41.941697]},"n2740":{"id":"n2740","loc":[-85.633713,41.947184]},"n2741":{"id":"n2741","loc":[-85.633651,41.94716]},"n2742":{"id":"n2742","loc":[-85.633704,41.947085]},"n2743":{"id":"n2743","loc":[-85.6336,41.947044]},"n2744":{"id":"n2744","loc":[-85.633506,41.947177]},"n2745":{"id":"n2745","loc":[-85.629586,41.952469]},"n2746":{"id":"n2746","loc":[-85.634723,41.953681]},"n2747":{"id":"n2747","loc":[-85.63478,41.959007]},"n2748":{"id":"n2748","loc":[-85.632793,41.94405],"tags":{"highway":"traffic_signals","traffic_signals":"signal"}},"n2749":{"id":"n2749","loc":[-85.634648,41.947325]},"n275":{"id":"n275","loc":[-85.63681,41.941705]},"n2750":{"id":"n2750","loc":[-85.625078,41.952097]},"n2751":{"id":"n2751","loc":[-85.633195,41.94734]},"n2752":{"id":"n2752","loc":[-85.626447,41.957168]},"n2753":{"id":"n2753","loc":[-85.632023,41.949012]},"n2754":{"id":"n2754","loc":[-85.630835,41.950656]},"n2755":{"id":"n2755","loc":[-85.634655,41.948612]},"n2756":{"id":"n2756","loc":[-85.636182,41.948605]},"n2757":{"id":"n2757","loc":[-85.634729,41.954667]},"n2758":{"id":"n2758","loc":[-85.634686,41.951159]},"n2759":{"id":"n2759","loc":[-85.636206,41.951146]},"n276":{"id":"n276","loc":[-85.63681,41.941714]},"n2760":{"id":"n2760","loc":[-85.634668,41.949891]},"n2761":{"id":"n2761","loc":[-85.634701,41.952422]},"n2762":{"id":"n2762","loc":[-85.634747,41.955907]},"n2763":{"id":"n2763","loc":[-85.627975,41.954695]},"n2764":{"id":"n2764","loc":[-85.626832,41.954698]},"n2765":{"id":"n2765","loc":[-85.632278,41.948624]},"n2766":{"id":"n2766","loc":[-85.628639,41.953725]},"n2767":{"id":"n2767","loc":[-85.636233,41.95241]},"n2768":{"id":"n2768","loc":[-85.631385,41.949913]},"n2769":{"id":"n2769","loc":[-85.630486,41.951194]},"n277":{"id":"n277","loc":[-85.636861,41.942041]},"n2770":{"id":"n2770","loc":[-85.624937,41.952088]},"n2771":{"id":"n2771","loc":[-85.624945,41.952022]},"n2772":{"id":"n2772","loc":[-85.636162,41.94731]},"n2773":{"id":"n2773","loc":[-85.636188,41.949881]},"n2774":{"id":"n2774","loc":[-85.631422,41.948294]},"n2775":{"id":"n2775","loc":[-85.632844,41.945547]},"n2776":{"id":"n2776","loc":[-85.632484,41.945344]},"n2777":{"id":"n2777","loc":[-85.631775,41.944636]},"n2778":{"id":"n2778","loc":[-85.632656,41.945471]},"n2779":{"id":"n2779","loc":[-85.631959,41.944827]},"n278":{"id":"n278","loc":[-85.636862,41.942099]},"n2780":{"id":"n2780","loc":[-85.631679,41.94438]},"n2781":{"id":"n2781","loc":[-85.625129,41.959272]},"n2782":{"id":"n2782","loc":[-85.632446,41.944861]},"n2783":{"id":"n2783","loc":[-85.632804,41.945477]},"n2784":{"id":"n2784","loc":[-85.632255,41.944962]},"n2785":{"id":"n2785","loc":[-85.632736,41.944757]},"n2786":{"id":"n2786","loc":[-85.632543,41.94486]},"n2787":{"id":"n2787","loc":[-85.632889,41.945561]},"n2788":{"id":"n2788","loc":[-85.632091,41.944949]},"n2789":{"id":"n2789","loc":[-85.632537,41.944713]},"n279":{"id":"n279","loc":[-85.636807,41.942099]},"n2790":{"id":"n2790","loc":[-85.632279,41.94485]},"n2791":{"id":"n2791","loc":[-85.632749,41.943247]},"n2792":{"id":"n2792","loc":[-85.632824,41.943152]},"n2793":{"id":"n2793","loc":[-85.632929,41.94317]},"n2794":{"id":"n2794","loc":[-85.632897,41.943078]},"n2795":{"id":"n2795","loc":[-85.632626,41.943231]},"n2796":{"id":"n2796","loc":[-85.634048,41.947257]},"n2797":{"id":"n2797","loc":[-85.634264,41.947252]},"n2798":{"id":"n2798","loc":[-85.635418,41.947317]},"n2799":{"id":"n2799","loc":[-85.635461,41.947237]},"n28":{"id":"n28","loc":[-85.63821,41.944308]},"n280":{"id":"n280","loc":[-85.636807,41.942126]},"n2800":{"id":"n2800","loc":[-85.632868,41.946229]},"n2801":{"id":"n2801","loc":[-85.633673,41.947242]},"n2802":{"id":"n2802","loc":[-85.623604,41.945881],"tags":{"amenity":"school","name":"Barrows School"}},"n2803":{"id":"n2803","loc":[-85.627401,41.943496]},"n2804":{"id":"n2804","loc":[-85.627403,41.943625]},"n2805":{"id":"n2805","loc":[-85.626409,41.943215]},"n2806":{"id":"n2806","loc":[-85.624884,41.943508]},"n2807":{"id":"n2807","loc":[-85.625191,41.943509]},"n2808":{"id":"n2808","loc":[-85.624882,41.94382]},"n2809":{"id":"n2809","loc":[-85.624893,41.945618]},"n281":{"id":"n281","loc":[-85.636726,41.942126]},"n2810":{"id":"n2810","loc":[-85.624912,41.946524]},"n2811":{"id":"n2811","loc":[-85.622721,41.946535]},"n2812":{"id":"n2812","loc":[-85.627399,41.94469]},"n2813":{"id":"n2813","loc":[-85.622716,41.945622]},"n2814":{"id":"n2814","loc":[-85.624886,41.944724]},"n2815":{"id":"n2815","loc":[-85.622674,41.944737]},"n2816":{"id":"n2816","loc":[-85.625092,41.945063]},"n2817":{"id":"n2817","loc":[-85.625233,41.945064]},"n2818":{"id":"n2818","loc":[-85.625229,41.944871]},"n2819":{"id":"n2819","loc":[-85.625066,41.944871]},"n282":{"id":"n282","loc":[-85.636726,41.942098]},"n2820":{"id":"n2820","loc":[-85.625024,41.944901]},"n2821":{"id":"n2821","loc":[-85.625025,41.944924]},"n2822":{"id":"n2822","loc":[-85.625087,41.944926]},"n2823":{"id":"n2823","loc":[-85.625349,41.944506]},"n2824":{"id":"n2824","loc":[-85.625347,41.944388]},"n2825":{"id":"n2825","loc":[-85.625152,41.94439]},"n2826":{"id":"n2826","loc":[-85.625152,41.944431]},"n2827":{"id":"n2827","loc":[-85.625134,41.944431]},"n2828":{"id":"n2828","loc":[-85.625136,41.944508]},"n2829":{"id":"n2829","loc":[-85.623236,41.946341]},"n283":{"id":"n283","loc":[-85.636708,41.942098]},"n2830":{"id":"n2830","loc":[-85.623241,41.946067]},"n2831":{"id":"n2831","loc":[-85.623207,41.946067]},"n2832":{"id":"n2832","loc":[-85.623212,41.945827]},"n2833":{"id":"n2833","loc":[-85.622981,41.945825]},"n2834":{"id":"n2834","loc":[-85.622976,41.946063]},"n2835":{"id":"n2835","loc":[-85.623006,41.946063]},"n2836":{"id":"n2836","loc":[-85.623002,41.946256]},"n2837":{"id":"n2837","loc":[-85.623075,41.946256]},"n2838":{"id":"n2838","loc":[-85.623074,41.946339]},"n2839":{"id":"n2839","loc":[-85.624574,41.951755]},"n284":{"id":"n284","loc":[-85.636708,41.942041]},"n2840":{"id":"n2840","loc":[-85.62498,41.951844]},"n2841":{"id":"n2841","loc":[-85.625086,41.95188]},"n2842":{"id":"n2842","loc":[-85.625135,41.951922]},"n2843":{"id":"n2843","loc":[-85.615273,41.945637]},"n2844":{"id":"n2844","loc":[-85.620172,41.945627]},"n2845":{"id":"n2845","loc":[-85.625167,41.951985]},"n2846":{"id":"n2846","loc":[-85.622741,41.947437]},"n2847":{"id":"n2847","loc":[-85.624907,41.947428]},"n2848":{"id":"n2848","loc":[-85.627046,41.940995]},"n2849":{"id":"n2849","loc":[-85.627295,41.941304]},"n285":{"id":"n285","loc":[-85.635618,41.941852]},"n2850":{"id":"n2850","loc":[-85.627352,41.94148]},"n2851":{"id":"n2851","loc":[-85.62737,41.942261]},"n2852":{"id":"n2852","loc":[-85.6264,41.942263]},"n2853":{"id":"n2853","loc":[-85.622769,41.949228]},"n2854":{"id":"n2854","loc":[-85.624937,41.949218]},"n2855":{"id":"n2855","loc":[-85.630001,41.944664]},"n2856":{"id":"n2856","loc":[-85.624873,41.942022]},"n2857":{"id":"n2857","loc":[-85.622761,41.948333]},"n2858":{"id":"n2858","loc":[-85.624924,41.948334]},"n2859":{"id":"n2859","loc":[-85.620051,41.94383]},"n286":{"id":"n286","loc":[-85.635621,41.94202]},"n2860":{"id":"n2860","loc":[-85.627629,41.946498]},"n2861":{"id":"n2861","loc":[-85.622757,41.950111]},"n2862":{"id":"n2862","loc":[-85.623685,41.954624]},"n2863":{"id":"n2863","loc":[-85.621459,41.944756]},"n2864":{"id":"n2864","loc":[-85.628637,41.944676]},"n2865":{"id":"n2865","loc":[-85.630125,41.944654]},"n2866":{"id":"n2866","loc":[-85.625196,41.952097]},"n2867":{"id":"n2867","loc":[-85.630257,41.944637]},"n2868":{"id":"n2868","loc":[-85.631247,41.944459]},"n2869":{"id":"n2869","loc":[-85.624867,41.94159]},"n287":{"id":"n287","loc":[-85.63524,41.942023]},"n2870":{"id":"n2870","loc":[-85.624958,41.950343]},"n2871":{"id":"n2871","loc":[-85.624948,41.950484]},"n2872":{"id":"n2872","loc":[-85.624813,41.950983]},"n2873":{"id":"n2873","loc":[-85.624723,41.951789]},"n2874":{"id":"n2874","loc":[-85.624262,41.9512]},"n2875":{"id":"n2875","loc":[-85.62414,41.951201]},"n2876":{"id":"n2876","loc":[-85.624139,41.95112]},"n2877":{"id":"n2877","loc":[-85.628481,41.945611]},"n2878":{"id":"n2878","loc":[-85.620072,41.946538]},"n2879":{"id":"n2879","loc":[-85.622763,41.95099]},"n288":{"id":"n288","loc":[-85.635237,41.941855]},"n2880":{"id":"n2880","loc":[-85.62814,41.946963]},"n2881":{"id":"n2881","loc":[-85.628245,41.947031]},"n2882":{"id":"n2882","loc":[-85.628331,41.947066]},"n2883":{"id":"n2883","loc":[-85.629722,41.944444],"tags":{"leisure":"park","name":"Scouter Park"}},"n2884":{"id":"n2884","loc":[-85.629977,41.943907]},"n2885":{"id":"n2885","loc":[-85.629947,41.943775]},"n2886":{"id":"n2886","loc":[-85.629899,41.943625]},"n2887":{"id":"n2887","loc":[-85.632286,41.944257]},"n2888":{"id":"n2888","loc":[-85.632523,41.944179]},"n2889":{"id":"n2889","loc":[-85.632141,41.944293]},"n289":{"id":"n289","loc":[-85.635568,41.940475]},"n2890":{"id":"n2890","loc":[-85.631571,41.9444]},"n2891":{"id":"n2891","loc":[-85.643236,41.941895]},"n2892":{"id":"n2892","loc":[-85.62865,41.945353]},"n2893":{"id":"n2893","loc":[-85.628594,41.945481]},"n2894":{"id":"n2894","loc":[-85.628581,41.947169]},"n2895":{"id":"n2895","loc":[-85.631843,41.943793]},"n2896":{"id":"n2896","loc":[-85.632299,41.943472]},"n2897":{"id":"n2897","loc":[-85.631519,41.944881]},"n2898":{"id":"n2898","loc":[-85.628429,41.947219]},"n2899":{"id":"n2899","loc":[-85.63145,41.945162]},"n29":{"id":"n29","loc":[-85.637963,41.944263]},"n290":{"id":"n290","loc":[-85.634584,41.940477]},"n2900":{"id":"n2900","loc":[-85.630939,41.945519]},"n2901":{"id":"n2901","loc":[-85.62903,41.945719]},"n2902":{"id":"n2902","loc":[-85.630521,41.945559]},"n2903":{"id":"n2903","loc":[-85.629294,41.945585]},"n2904":{"id":"n2904","loc":[-85.629845,41.945543]},"n2905":{"id":"n2905","loc":[-85.631497,41.944625]},"n2906":{"id":"n2906","loc":[-85.630281,41.945553]},"n2907":{"id":"n2907","loc":[-85.628553,41.946973]},"n2908":{"id":"n2908","loc":[-85.631383,41.945338]},"n2909":{"id":"n2909","loc":[-85.628843,41.946103]},"n291":{"id":"n291","loc":[-85.634583,41.940203]},"n2910":{"id":"n2910","loc":[-85.631193,41.945473]},"n2911":{"id":"n2911","loc":[-85.628897,41.945944]},"n2912":{"id":"n2912","loc":[-85.628789,41.946454]},"n2913":{"id":"n2913","loc":[-85.632548,41.944563]},"n2914":{"id":"n2914","loc":[-85.627527,41.944555]},"n2915":{"id":"n2915","loc":[-85.62752,41.943726]},"n2916":{"id":"n2916","loc":[-85.627894,41.943723]},"n2917":{"id":"n2917","loc":[-85.627897,41.943919]},"n2918":{"id":"n2918","loc":[-85.627991,41.943934]},"n2919":{"id":"n2919","loc":[-85.628082,41.943966]},"n292":{"id":"n292","loc":[-85.635567,41.940201]},"n2920":{"id":"n2920","loc":[-85.628177,41.944015]},"n2921":{"id":"n2921","loc":[-85.628193,41.944048]},"n2922":{"id":"n2922","loc":[-85.628167,41.944054]},"n2923":{"id":"n2923","loc":[-85.628193,41.944094]},"n2924":{"id":"n2924","loc":[-85.628213,41.944144]},"n2925":{"id":"n2925","loc":[-85.628214,41.944199]},"n2926":{"id":"n2926","loc":[-85.62833,41.944196]},"n2927":{"id":"n2927","loc":[-85.628328,41.944262]},"n2928":{"id":"n2928","loc":[-85.628173,41.944262]},"n2929":{"id":"n2929","loc":[-85.628171,41.944293]},"n293":{"id":"n293","loc":[-85.635816,41.942673],"tags":{"crossing":"zebra","highway":"crossing"}},"n2930":{"id":"n2930","loc":[-85.628039,41.944296]},"n2931":{"id":"n2931","loc":[-85.62804,41.944329]},"n2932":{"id":"n2932","loc":[-85.627829,41.944335]},"n2933":{"id":"n2933","loc":[-85.627835,41.94455]},"n2936":{"id":"n2936","loc":[-85.632823,41.945994]},"n294":{"id":"n294","loc":[-85.635696,41.942712]},"n2940":{"id":"n2940","loc":[-85.632192,41.945973]},"n2941":{"id":"n2941","loc":[-85.63226,41.94587]},"n2942":{"id":"n2942","loc":[-85.632721,41.946036]},"n2943":{"id":"n2943","loc":[-85.632641,41.946142]},"n2944":{"id":"n2944","loc":[-85.62937,41.947467]},"n2945":{"id":"n2945","loc":[-85.62959,41.942936]},"n2946":{"id":"n2946","loc":[-85.629551,41.94284]},"n2947":{"id":"n2947","loc":[-85.629501,41.942704]},"n2948":{"id":"n2948","loc":[-85.629472,41.942578]},"n2949":{"id":"n2949","loc":[-85.629361,41.941801]},"n295":{"id":"n295","loc":[-85.635679,41.941962]},"n2950":{"id":"n2950","loc":[-85.629339,41.941716]},"n2951":{"id":"n2951","loc":[-85.629315,41.94166]},"n2952":{"id":"n2952","loc":[-85.629279,41.941602]},"n2953":{"id":"n2953","loc":[-85.629227,41.941556]},"n2954":{"id":"n2954","loc":[-85.624261,41.95112]},"n2955":{"id":"n2955","loc":[-85.629153,41.941524]},"n2956":{"id":"n2956","loc":[-85.626904,41.941098]},"n2957":{"id":"n2957","loc":[-85.624588,41.951294]},"n2958":{"id":"n2958","loc":[-85.631844,41.942945]},"n2959":{"id":"n2959","loc":[-85.625854,41.949222]},"n296":{"id":"n296","loc":[-85.635672,41.941337]},"n2960":{"id":"n2960","loc":[-85.625146,41.955238]},"n2961":{"id":"n2961","loc":[-85.626745,41.948296]},"n2962":{"id":"n2962","loc":[-85.625721,41.95524]},"n2963":{"id":"n2963","loc":[-85.624706,41.952317]},"n2964":{"id":"n2964","loc":[-85.62609,41.956147]},"n2965":{"id":"n2965","loc":[-85.624401,41.954928]},"n2966":{"id":"n2966","loc":[-85.626558,41.955367]},"n2967":{"id":"n2967","loc":[-85.62468,41.955096]},"n2968":{"id":"n2968","loc":[-85.624159,41.953929]},"n2969":{"id":"n2969","loc":[-85.62506,41.951113]},"n297":{"id":"n297","loc":[-85.635658,41.941284]},"n2970":{"id":"n2970","loc":[-85.624942,41.951591]},"n2971":{"id":"n2971","loc":[-85.627399,41.947546]},"n2972":{"id":"n2972","loc":[-85.627695,41.947404]},"n2973":{"id":"n2973","loc":[-85.625925,41.94896]},"n2974":{"id":"n2974","loc":[-85.625725,41.950211]},"n2975":{"id":"n2975","loc":[-85.627008,41.947963]},"n2976":{"id":"n2976","loc":[-85.624373,41.953458]},"n2977":{"id":"n2977","loc":[-85.624137,41.954392]},"n2978":{"id":"n2978","loc":[-85.628257,41.947307]},"n2979":{"id":"n2979","loc":[-85.625281,41.95066]},"n298":{"id":"n298","loc":[-85.635602,41.941166]},"n2980":{"id":"n2980","loc":[-85.625865,41.949804]},"n2981":{"id":"n2981","loc":[-85.626508,41.955932]},"n2982":{"id":"n2982","loc":[-85.626333,41.955216]},"n2983":{"id":"n2983","loc":[-85.626637,41.955676]},"n2984":{"id":"n2984","loc":[-85.624223,41.954599]},"n2985":{"id":"n2985","loc":[-85.626219,41.948671]},"n2986":{"id":"n2986","loc":[-85.624556,41.953043]},"n2987":{"id":"n2987","loc":[-85.625598,41.956302]},"n2988":{"id":"n2988","loc":[-85.624571,41.952971]},"n2989":{"id":"n2989","loc":[-85.627141,41.940727]},"n299":{"id":"n299","loc":[-85.635598,41.941138]},"n2990":{"id":"n2990","loc":[-85.627102,41.939144]},"n2991":{"id":"n2991","loc":[-85.627127,41.940086]},"n2992":{"id":"n2992","loc":[-85.627116,41.940843]},"n2993":{"id":"n2993","loc":[-85.627132,41.9402]},"n2994":{"id":"n2994","loc":[-85.629734,41.940078]},"n2995":{"id":"n2995","loc":[-85.6276,41.937412]},"n2996":{"id":"n2996","loc":[-85.627451,41.937549]},"n2997":{"id":"n2997","loc":[-85.627375,41.937618]},"n2998":{"id":"n2998","loc":[-85.627278,41.937728]},"n2999":{"id":"n2999","loc":[-85.627199,41.937842]},"n3":{"id":"n3","loc":[-85.627345,41.953983]},"n30":{"id":"n30","loc":[-85.637882,41.944205]},"n300":{"id":"n300","loc":[-85.635614,41.941076]},"n3000":{"id":"n3000","loc":[-85.627141,41.937981]},"n3001":{"id":"n3001","loc":[-85.627109,41.938153]},"n3002":{"id":"n3002","loc":[-85.627101,41.938699]},"n3003":{"id":"n3003","loc":[-85.628311,41.942261]},"n3004":{"id":"n3004","loc":[-85.628439,41.940082]},"n3005":{"id":"n3005","loc":[-85.619538,41.942622],"tags":{"leisure":"slipway"}},"n3006":{"id":"n3006","loc":[-85.619872,41.942618]},"n3007":{"id":"n3007","loc":[-85.619755,41.942612]},"n3008":{"id":"n3008","loc":[-85.619647,41.942628]},"n3009":{"id":"n3009","loc":[-85.619415,41.942626]},"n301":{"id":"n301","loc":[-85.635659,41.940956]},"n3010":{"id":"n3010","loc":[-85.619212,41.942623]},"n3011":{"id":"n3011","loc":[-85.631485,41.942472]},"n3012":{"id":"n3012","loc":[-85.630986,41.941786]},"n3013":{"id":"n3013","loc":[-85.631797,41.942006]},"n3014":{"id":"n3014","loc":[-85.630972,41.941162]},"n3015":{"id":"n3015","loc":[-85.631396,41.941611],"tags":{"railway":"level_crossing"}},"n3016":{"id":"n3016","loc":[-85.631878,41.941545]},"n3017":{"id":"n3017","loc":[-85.630461,41.94055]},"n3018":{"id":"n3018","loc":[-85.629751,41.939539],"tags":{"railway":"level_crossing"}},"n3019":{"id":"n3019","loc":[-85.631663,41.941513]},"n302":{"id":"n302","loc":[-85.635666,41.940922]},"n3020":{"id":"n3020","loc":[-85.631328,41.941375]},"n3021":{"id":"n3021","loc":[-85.632554,41.941779]},"n3022":{"id":"n3022","loc":[-85.63245,41.941769]},"n3023":{"id":"n3023","loc":[-85.632475,41.941644]},"n3024":{"id":"n3024","loc":[-85.632581,41.941654]},"n3025":{"id":"n3025","loc":[-85.631957,41.941352]},"n3026":{"id":"n3026","loc":[-85.632293,41.941139]},"n3027":{"id":"n3027","loc":[-85.632315,41.941153]},"n3028":{"id":"n3028","loc":[-85.632302,41.941262]},"n3029":{"id":"n3029","loc":[-85.63237,41.941267]},"n303":{"id":"n303","loc":[-85.635667,41.940877]},"n3030":{"id":"n3030","loc":[-85.632356,41.941538]},"n3031":{"id":"n3031","loc":[-85.632134,41.941678]},"n3032":{"id":"n3032","loc":[-85.631942,41.941687]},"n3033":{"id":"n3033","loc":[-85.63203,41.941694]},"n3034":{"id":"n3034","loc":[-85.632166,41.941555]},"n3035":{"id":"n3035","loc":[-85.632412,41.941416]},"n3036":{"id":"n3036","loc":[-85.63248,41.941342]},"n3037":{"id":"n3037","loc":[-85.632502,41.941259]},"n3038":{"id":"n3038","loc":[-85.632453,41.941161]},"n3039":{"id":"n3039","loc":[-85.63235,41.941103]},"n304":{"id":"n304","loc":[-85.635668,41.940655]},"n3040":{"id":"n3040","loc":[-85.632236,41.941118]},"n3041":{"id":"n3041","loc":[-85.631894,41.941355]},"n3042":{"id":"n3042","loc":[-85.631859,41.941411]},"n3043":{"id":"n3043","loc":[-85.632011,41.941587]},"n3044":{"id":"n3044","loc":[-85.632446,41.941379]},"n3045":{"id":"n3045","loc":[-85.632511,41.941416]},"n3046":{"id":"n3046","loc":[-85.632545,41.941634]},"n3047":{"id":"n3047","loc":[-85.632612,41.94164]},"n3048":{"id":"n3048","loc":[-85.632595,41.942197]},"n3049":{"id":"n3049","loc":[-85.632565,41.942241]},"n305":{"id":"n305","loc":[-85.635628,41.940617]},"n3050":{"id":"n3050","loc":[-85.632515,41.942256]},"n3051":{"id":"n3051","loc":[-85.63245,41.94223]},"n3052":{"id":"n3052","loc":[-85.632401,41.942174]},"n3053":{"id":"n3053","loc":[-85.632391,41.942115]},"n3054":{"id":"n3054","loc":[-85.632029,41.941859]},"n3055":{"id":"n3055","loc":[-85.631828,41.941639]},"n3056":{"id":"n3056","loc":[-85.631829,41.941508]},"n3057":{"id":"n3057","loc":[-85.631281,41.94312]},"n3058":{"id":"n3058","loc":[-85.631421,41.943065]},"n3059":{"id":"n3059","loc":[-85.631339,41.942949]},"n306":{"id":"n306","loc":[-85.635623,41.940272]},"n3060":{"id":"n3060","loc":[-85.631199,41.943004]},"n3061":{"id":"n3061","loc":[-85.631102,41.942931]},"n3062":{"id":"n3062","loc":[-85.631009,41.942809]},"n3063":{"id":"n3063","loc":[-85.631383,41.94265]},"n3064":{"id":"n3064","loc":[-85.631477,41.942773]},"n3065":{"id":"n3065","loc":[-85.630638,41.942809]},"n3066":{"id":"n3066","loc":[-85.630738,41.942943]},"n3067":{"id":"n3067","loc":[-85.630841,41.9429]},"n3068":{"id":"n3068","loc":[-85.630741,41.942766]},"n3069":{"id":"n3069","loc":[-85.63054,41.942603]},"n307":{"id":"n307","loc":[-85.635651,41.940183]},"n3070":{"id":"n3070","loc":[-85.630498,41.942619]},"n3071":{"id":"n3071","loc":[-85.630567,41.942718]},"n3072":{"id":"n3072","loc":[-85.630616,41.942698]},"n3073":{"id":"n3073","loc":[-85.630642,41.94273]},"n3074":{"id":"n3074","loc":[-85.630686,41.942714]},"n3075":{"id":"n3075","loc":[-85.630715,41.942754]},"n3076":{"id":"n3076","loc":[-85.6309,41.942681]},"n3077":{"id":"n3077","loc":[-85.630843,41.942605]},"n3078":{"id":"n3078","loc":[-85.6309,41.942581]},"n3079":{"id":"n3079","loc":[-85.630832,41.942487]},"n308":{"id":"n308","loc":[-85.63577,41.940183],"tags":{"crossing":"zebra","highway":"crossing"}},"n3080":{"id":"n3080","loc":[-85.630773,41.942509]},"n3081":{"id":"n3081","loc":[-85.630718,41.942436]},"n3082":{"id":"n3082","loc":[-85.630485,41.942524]},"n3083":{"id":"n3083","loc":[-85.631468,41.941233]},"n3084":{"id":"n3084","loc":[-85.631334,41.94114]},"n3085":{"id":"n3085","loc":[-85.632052,41.940568]},"n3086":{"id":"n3086","loc":[-85.63219,41.940663]},"n3087":{"id":"n3087","loc":[-85.631323,41.940834]},"n3088":{"id":"n3088","loc":[-85.631122,41.941002]},"n3089":{"id":"n3089","loc":[-85.631321,41.941133]},"n309":{"id":"n309","loc":[-85.636939,41.942544]},"n3090":{"id":"n3090","loc":[-85.631521,41.940966]},"n3091":{"id":"n3091","loc":[-85.631103,41.940253]},"n3092":{"id":"n3092","loc":[-85.631226,41.940211]},"n3093":{"id":"n3093","loc":[-85.631597,41.940805]},"n3094":{"id":"n3094","loc":[-85.631474,41.940847]},"n3095":{"id":"n3095","loc":[-85.631811,41.940534]},"n3096":{"id":"n3096","loc":[-85.631588,41.94061]},"n3097":{"id":"n3097","loc":[-85.631438,41.940366]},"n3098":{"id":"n3098","loc":[-85.631661,41.94029]},"n3099":{"id":"n3099","loc":[-85.630621,41.940041]},"n31":{"id":"n31","loc":[-85.63827,41.944203]},"n310":{"id":"n310","loc":[-85.636323,41.942552]},"n3100":{"id":"n3100","loc":[-85.630436,41.939773]},"n3101":{"id":"n3101","loc":[-85.63059,41.939714]},"n3102":{"id":"n3102","loc":[-85.630775,41.939983]},"n3103":{"id":"n3103","loc":[-85.63047,41.940167]},"n3104":{"id":"n3104","loc":[-85.63013,41.939686]},"n3105":{"id":"n3105","loc":[-85.630302,41.939618]},"n3106":{"id":"n3106","loc":[-85.630641,41.9401]},"n3107":{"id":"n3107","loc":[-85.630966,41.940619]},"n3108":{"id":"n3108","loc":[-85.630874,41.940493]},"n3109":{"id":"n3109","loc":[-85.630933,41.940469]},"n311":{"id":"n311","loc":[-85.636257,41.942555]},"n3110":{"id":"n3110","loc":[-85.630763,41.940236]},"n3111":{"id":"n3111","loc":[-85.63088,41.940189]},"n3112":{"id":"n3112","loc":[-85.631142,41.940548]},"n3113":{"id":"n3113","loc":[-85.630958,41.940871]},"n3114":{"id":"n3114","loc":[-85.630874,41.940778]},"n3115":{"id":"n3115","loc":[-85.631062,41.940684]},"n3116":{"id":"n3116","loc":[-85.631146,41.940777]},"n3117":{"id":"n3117","loc":[-85.632031,41.940575]},"n3118":{"id":"n3118","loc":[-85.631777,41.940186]},"n3119":{"id":"n3119","loc":[-85.631346,41.940179]},"n312":{"id":"n312","loc":[-85.636208,41.942561]},"n3120":{"id":"n3120","loc":[-85.631342,41.94012]},"n3121":{"id":"n3121","loc":[-85.631831,41.940118]},"n3122":{"id":"n3122","loc":[-85.632115,41.940543]},"n3123":{"id":"n3123","loc":[-85.631031,41.941683]},"n3124":{"id":"n3124","loc":[-85.630981,41.941608]},"n3125":{"id":"n3125","loc":[-85.631209,41.941516]},"n3126":{"id":"n3126","loc":[-85.631264,41.941586]},"n3127":{"id":"n3127","loc":[-85.630938,41.94155]},"n3128":{"id":"n3128","loc":[-85.631156,41.941462]},"n3129":{"id":"n3129","loc":[-85.631197,41.94152]},"n313":{"id":"n313","loc":[-85.636159,41.942573]},"n3130":{"id":"n3130","loc":[-85.630895,41.941485]},"n3131":{"id":"n3131","loc":[-85.630824,41.941389]},"n3132":{"id":"n3132","loc":[-85.630986,41.941323]},"n3133":{"id":"n3133","loc":[-85.631057,41.941419]},"n3134":{"id":"n3134","loc":[-85.630777,41.941328]},"n3135":{"id":"n3135","loc":[-85.630907,41.941274]},"n3136":{"id":"n3136","loc":[-85.630953,41.941335]},"n3137":{"id":"n3137","loc":[-85.630797,41.941247]},"n3138":{"id":"n3138","loc":[-85.630701,41.94117]},"n3139":{"id":"n3139","loc":[-85.630829,41.941113]},"n314":{"id":"n314","loc":[-85.635743,41.942881]},"n3140":{"id":"n3140","loc":[-85.6309,41.941201]},"n3141":{"id":"n3141","loc":[-85.630765,41.941206]},"n3142":{"id":"n3142","loc":[-85.630739,41.941218]},"n3143":{"id":"n3143","loc":[-85.630582,41.941039]},"n3144":{"id":"n3144","loc":[-85.630412,41.940818]},"n3145":{"id":"n3145","loc":[-85.630509,41.940777]},"n3146":{"id":"n3146","loc":[-85.630678,41.941004]},"n3147":{"id":"n3147","loc":[-85.630773,41.942166]},"n3148":{"id":"n3148","loc":[-85.630708,41.942074]},"n3149":{"id":"n3149","loc":[-85.630863,41.942013]},"n315":{"id":"n315","loc":[-85.635452,41.942966]},"n3150":{"id":"n3150","loc":[-85.630928,41.942105]},"n3151":{"id":"n3151","loc":[-85.630701,41.942026]},"n3152":{"id":"n3152","loc":[-85.630665,41.941971]},"n3153":{"id":"n3153","loc":[-85.630793,41.941918]},"n3154":{"id":"n3154","loc":[-85.630837,41.94197]},"n3155":{"id":"n3155","loc":[-85.630757,41.941871]},"n3156":{"id":"n3156","loc":[-85.630629,41.941923]},"n3157":{"id":"n3157","loc":[-85.630694,41.941783]},"n3158":{"id":"n3158","loc":[-85.630534,41.941847]},"n3159":{"id":"n3159","loc":[-85.630598,41.941935]},"n316":{"id":"n316","loc":[-85.634911,41.943118]},"n3160":{"id":"n3160","loc":[-85.631548,41.93938]},"n3161":{"id":"n3161","loc":[-85.631525,41.939919]},"n3162":{"id":"n3162","loc":[-85.631648,41.940043]},"n3163":{"id":"n3163","loc":[-85.624586,41.951121]},"n3164":{"id":"n3164","loc":[-85.622139,41.952064]},"n3165":{"id":"n3165","loc":[-85.622141,41.952144]},"n3166":{"id":"n3166","loc":[-85.621977,41.952146]},"n3167":{"id":"n3167","loc":[-85.621978,41.952211]},"n3168":{"id":"n3168","loc":[-85.62191,41.952212]},"n3169":{"id":"n3169","loc":[-85.633628,41.935437]},"n317":{"id":"n317","loc":[-85.634743,41.943167]},"n3170":{"id":"n3170","loc":[-85.632849,41.935518]},"n3171":{"id":"n3171","loc":[-85.632376,41.93574]},"n3172":{"id":"n3172","loc":[-85.631517,41.935897]},"n3173":{"id":"n3173","loc":[-85.630433,41.936124]},"n3174":{"id":"n3174","loc":[-85.630207,41.936427]},"n3175":{"id":"n3175","loc":[-85.630346,41.936795]},"n3176":{"id":"n3176","loc":[-85.62996,41.936974]},"n3177":{"id":"n3177","loc":[-85.629916,41.937488]},"n3178":{"id":"n3178","loc":[-85.629946,41.937802]},"n3179":{"id":"n3179","loc":[-85.629977,41.937905]},"n318":{"id":"n318","loc":[-85.634401,41.94328]},"n3180":{"id":"n3180","loc":[-85.63016,41.937909]},"n3181":{"id":"n3181","loc":[-85.630804,41.937791]},"n3182":{"id":"n3182","loc":[-85.631688,41.937808]},"n3183":{"id":"n3183","loc":[-85.631685,41.938008]},"n3184":{"id":"n3184","loc":[-85.631845,41.938116]},"n3185":{"id":"n3185","loc":[-85.63207,41.938181]},"n3186":{"id":"n3186","loc":[-85.632143,41.938371]},"n3187":{"id":"n3187","loc":[-85.632056,41.938435]},"n3188":{"id":"n3188","loc":[-85.631787,41.938457]},"n3189":{"id":"n3189","loc":[-85.631657,41.938728]},"n319":{"id":"n319","loc":[-85.634345,41.943299]},"n3190":{"id":"n3190","loc":[-85.631595,41.93775]},"n3191":{"id":"n3191","loc":[-85.630264,41.937839]},"n3192":{"id":"n3192","loc":[-85.628591,41.948536]},"n3193":{"id":"n3193","loc":[-85.63205,41.951181]},"n3194":{"id":"n3194","loc":[-85.632034,41.949909]},"n3195":{"id":"n3195","loc":[-85.630841,41.951191]},"n3196":{"id":"n3196","loc":[-85.632083,41.9537]},"n3197":{"id":"n3197","loc":[-85.630929,41.959037]},"n3198":{"id":"n3198","loc":[-85.632151,41.959028]},"n3199":{"id":"n3199","loc":[-85.630911,41.957428]},"n32":{"id":"n32","loc":[-85.638273,41.944246]},"n320":{"id":"n320","loc":[-85.634287,41.943326]},"n3200":{"id":"n3200","loc":[-85.63213,41.957427]},"n3201":{"id":"n3201","loc":[-85.632072,41.952447]},"n3202":{"id":"n3202","loc":[-85.632095,41.954677]},"n3203":{"id":"n3203","loc":[-85.632111,41.955911]},"n3204":{"id":"n3204","loc":[-85.630855,41.952457]},"n3205":{"id":"n3205","loc":[-85.630869,41.953709]},"n3206":{"id":"n3206","loc":[-85.63088,41.954682]},"n3207":{"id":"n3207","loc":[-85.630894,41.955913]},"n3208":{"id":"n3208","loc":[-85.633214,41.948619]},"n3209":{"id":"n3209","loc":[-85.633253,41.951171]},"n321":{"id":"n321","loc":[-85.634233,41.943354]},"n3210":{"id":"n3210","loc":[-85.633234,41.949901]},"n3211":{"id":"n3211","loc":[-85.633922,41.948616]},"n3212":{"id":"n3212","loc":[-85.625188,41.947832]},"n3213":{"id":"n3213","loc":[-85.625208,41.947775]},"n3214":{"id":"n3214","loc":[-85.625229,41.94776]},"n3215":{"id":"n3215","loc":[-85.625201,41.947749]},"n3216":{"id":"n3216","loc":[-85.625168,41.947707]},"n3217":{"id":"n3217","loc":[-85.625171,41.947609]},"n3218":{"id":"n3218","loc":[-85.625213,41.947564]},"n3219":{"id":"n3219","loc":[-85.62529,41.94756]},"n322":{"id":"n322","loc":[-85.634099,41.943429]},"n3220":{"id":"n3220","loc":[-85.625303,41.947533]},"n3221":{"id":"n3221","loc":[-85.625344,41.947482]},"n3222":{"id":"n3222","loc":[-85.625442,41.947468]},"n3223":{"id":"n3223","loc":[-85.62565,41.947494]},"n3224":{"id":"n3224","loc":[-85.625726,41.947613]},"n3225":{"id":"n3225","loc":[-85.625703,41.947728]},"n3226":{"id":"n3226","loc":[-85.625534,41.94781]},"n3227":{"id":"n3227","loc":[-85.625391,41.947822]},"n3228":{"id":"n3228","loc":[-85.625304,41.947859]},"n3229":{"id":"n3229","loc":[-85.625203,41.947885]},"n323":{"id":"n323","loc":[-85.633958,41.943507],"tags":{"highway":"crossing"}},"n3230":{"id":"n3230","loc":[-85.624691,41.948659]},"n3231":{"id":"n3231","loc":[-85.624328,41.948661]},"n3232":{"id":"n3232","loc":[-85.624331,41.949046]},"n3233":{"id":"n3233","loc":[-85.624694,41.949045]},"n3234":{"id":"n3234","loc":[-85.623623,41.949606]},"n3235":{"id":"n3235","loc":[-85.623623,41.9497]},"n3236":{"id":"n3236","loc":[-85.623357,41.9497]},"n3237":{"id":"n3237","loc":[-85.623357,41.949614]},"n3238":{"id":"n3238","loc":[-85.623974,41.949429]},"n3239":{"id":"n3239","loc":[-85.623974,41.949605]},"n324":{"id":"n324","loc":[-85.633698,41.943651],"tags":{"railway":"crossing"}},"n3240":{"id":"n3240","loc":[-85.624501,41.951226]},"n3241":{"id":"n3241","loc":[-85.624501,41.951123]},"n3242":{"id":"n3242","loc":[-85.624319,41.951123]},"n3243":{"id":"n3243","loc":[-85.624319,41.951226]},"n3244":{"id":"n3244","loc":[-85.624121,41.950866]},"n3245":{"id":"n3245","loc":[-85.624115,41.950525]},"n3246":{"id":"n3246","loc":[-85.624315,41.950523]},"n3247":{"id":"n3247","loc":[-85.62432,41.950865]},"n3248":{"id":"n3248","loc":[-85.624393,41.950867]},"n3249":{"id":"n3249","loc":[-85.62439,41.950596]},"n325":{"id":"n325","loc":[-85.633508,41.943757]},"n3250":{"id":"n3250","loc":[-85.624673,41.950594]},"n3251":{"id":"n3251","loc":[-85.624675,41.95082]},"n3252":{"id":"n3252","loc":[-85.62451,41.950821]},"n3253":{"id":"n3253","loc":[-85.62451,41.950866]},"n3254":{"id":"n3254","loc":[-85.624101,41.949346]},"n3255":{"id":"n3255","loc":[-85.624244,41.949346]},"n3256":{"id":"n3256","loc":[-85.624244,41.949368]},"n3257":{"id":"n3257","loc":[-85.62434,41.949368]},"n3258":{"id":"n3258","loc":[-85.624342,41.949351]},"n3259":{"id":"n3259","loc":[-85.624725,41.949348]},"n326":{"id":"n326","loc":[-85.634839,41.942974]},"n3260":{"id":"n3260","loc":[-85.624755,41.950495]},"n3261":{"id":"n3261","loc":[-85.624121,41.950502]},"n3262":{"id":"n3262","loc":[-85.625453,41.950163]},"n3263":{"id":"n3263","loc":[-85.625454,41.949976]},"n3264":{"id":"n3264","loc":[-85.625549,41.949977]},"n3265":{"id":"n3265","loc":[-85.62555,41.949833]},"n3266":{"id":"n3266","loc":[-85.625577,41.949833]},"n3267":{"id":"n3267","loc":[-85.625578,41.949656]},"n3268":{"id":"n3268","loc":[-85.625195,41.949655]},"n3269":{"id":"n3269","loc":[-85.625192,41.950162]},"n327":{"id":"n327","loc":[-85.634657,41.943028]},"n3270":{"id":"n3270","loc":[-85.622992,41.949614]},"n3271":{"id":"n3271","loc":[-85.622991,41.949431]},"n3272":{"id":"n3272","loc":[-85.620103,41.951]},"n3273":{"id":"n3273","loc":[-85.605644,41.947468]},"n3274":{"id":"n3274","loc":[-85.617421,41.947457]},"n3275":{"id":"n3275","loc":[-85.620078,41.947444]},"n3276":{"id":"n3276","loc":[-85.620087,41.94924]},"n3277":{"id":"n3277","loc":[-85.62156,41.948333]},"n3278":{"id":"n3278","loc":[-85.620106,41.950132]},"n3279":{"id":"n3279","loc":[-85.637412,41.951136]},"n328":{"id":"n328","loc":[-85.634222,41.943152]},"n3280":{"id":"n3280","loc":[-85.635429,41.948608]},"n3281":{"id":"n3281","loc":[-85.635047,41.947788]},"n3282":{"id":"n3282","loc":[-85.635048,41.947796]},"n3283":{"id":"n3283","loc":[-85.635002,41.947797]},"n3284":{"id":"n3284","loc":[-85.635002,41.947788]},"n3285":{"id":"n3285","loc":[-85.634914,41.94779]},"n3286":{"id":"n3286","loc":[-85.634913,41.947753]},"n3287":{"id":"n3287","loc":[-85.63494,41.947753]},"n3288":{"id":"n3288","loc":[-85.634938,41.947708]},"n3289":{"id":"n3289","loc":[-85.635124,41.947705]},"n329":{"id":"n329","loc":[-85.634099,41.943202]},"n3290":{"id":"n3290","loc":[-85.635126,41.947787]},"n3291":{"id":"n3291","loc":[-85.634972,41.947599]},"n3292":{"id":"n3292","loc":[-85.634921,41.9476]},"n3293":{"id":"n3293","loc":[-85.63485,41.947546]},"n3294":{"id":"n3294","loc":[-85.63485,41.947508]},"n3295":{"id":"n3295","loc":[-85.634924,41.947457]},"n3296":{"id":"n3296","loc":[-85.634967,41.947456]},"n3297":{"id":"n3297","loc":[-85.635041,41.947512]},"n3298":{"id":"n3298","loc":[-85.635041,41.947542]},"n3299":{"id":"n3299","loc":[-85.634244,41.947839]},"n33":{"id":"n33","loc":[-85.638257,41.944188]},"n330":{"id":"n330","loc":[-85.634093,41.943138]},"n3300":{"id":"n3300","loc":[-85.634243,41.947793]},"n3301":{"id":"n3301","loc":[-85.634244,41.947686]},"n3302":{"id":"n3302","loc":[-85.634243,41.947657]},"n3303":{"id":"n3303","loc":[-85.634462,41.947653]},"n3304":{"id":"n3304","loc":[-85.634468,41.947835]},"n3305":{"id":"n3305","loc":[-85.634416,41.948006]},"n3306":{"id":"n3306","loc":[-85.634415,41.947898]},"n3307":{"id":"n3307","loc":[-85.634275,41.947899]},"n3308":{"id":"n3308","loc":[-85.634275,41.947927]},"n3309":{"id":"n3309","loc":[-85.63425,41.947927]},"n331":{"id":"n331","loc":[-85.633938,41.943291]},"n3310":{"id":"n3310","loc":[-85.63425,41.947976]},"n3311":{"id":"n3311","loc":[-85.634274,41.947976]},"n3312":{"id":"n3312","loc":[-85.634275,41.948007]},"n3313":{"id":"n3313","loc":[-85.634342,41.947635]},"n3314":{"id":"n3314","loc":[-85.634339,41.947497]},"n3315":{"id":"n3315","loc":[-85.634313,41.94748]},"n3316":{"id":"n3316","loc":[-85.634287,41.947474]},"n3317":{"id":"n3317","loc":[-85.63498,41.94815]},"n3318":{"id":"n3318","loc":[-85.634891,41.94815]},"n3319":{"id":"n3319","loc":[-85.634892,41.948169]},"n332":{"id":"n332","loc":[-85.633535,41.943511],"tags":{"railway":"crossing"}},"n3320":{"id":"n3320","loc":[-85.634852,41.948169]},"n3321":{"id":"n3321","loc":[-85.634853,41.948268]},"n3322":{"id":"n3322","loc":[-85.634832,41.948268]},"n3323":{"id":"n3323","loc":[-85.634832,41.948296]},"n3324":{"id":"n3324","loc":[-85.634965,41.948295]},"n3325":{"id":"n3325","loc":[-85.634966,41.948321]},"n3326":{"id":"n3326","loc":[-85.634999,41.948321]},"n3327":{"id":"n3327","loc":[-85.634999,41.948295]},"n3328":{"id":"n3328","loc":[-85.635175,41.948293]},"n3329":{"id":"n3329","loc":[-85.635175,41.948262]},"n333":{"id":"n333","loc":[-85.63339,41.943596]},"n3330":{"id":"n3330","loc":[-85.635159,41.948262]},"n3331":{"id":"n3331","loc":[-85.635158,41.948152]},"n3332":{"id":"n3332","loc":[-85.635067,41.948152]},"n3333":{"id":"n3333","loc":[-85.635065,41.947966]},"n3334":{"id":"n3334","loc":[-85.634979,41.947966]},"n3335":{"id":"n3335","loc":[-85.634307,41.948326]},"n3336":{"id":"n3336","loc":[-85.634305,41.948298]},"n3337":{"id":"n3337","loc":[-85.634331,41.948055]},"n3338":{"id":"n3338","loc":[-85.634331,41.948046]},"n3339":{"id":"n3339","loc":[-85.634435,41.948047]},"n334":{"id":"n334","loc":[-85.632842,41.943895]},"n3340":{"id":"n3340","loc":[-85.634434,41.948375]},"n3341":{"id":"n3341","loc":[-85.634463,41.948373]},"n3342":{"id":"n3342","loc":[-85.634464,41.948456]},"n3343":{"id":"n3343","loc":[-85.63443,41.948457]},"n3344":{"id":"n3344","loc":[-85.634432,41.948505]},"n3345":{"id":"n3345","loc":[-85.637386,41.94906]},"n3346":{"id":"n3346","loc":[-85.637113,41.9486]},"n3347":{"id":"n3347","loc":[-85.635448,41.949424]},"n335":{"id":"n335","loc":[-85.633856,41.943315]},"n3352":{"id":"n3352","loc":[-85.635457,41.949787]},"n3353":{"id":"n3353","loc":[-85.635459,41.949886]},"n336":{"id":"n336","loc":[-85.633697,41.943405]},"n337":{"id":"n337","loc":[-85.63347,41.943181]},"n3372":{"id":"n3372","loc":[-85.634423,41.950964]},"n3373":{"id":"n3373","loc":[-85.634424,41.95074]},"n3374":{"id":"n3374","loc":[-85.634394,41.950284]},"n3375":{"id":"n3375","loc":[-85.634398,41.950626]},"n3376":{"id":"n3376","loc":[-85.63452,41.951063]},"n3377":{"id":"n3377","loc":[-85.634511,41.949977]},"n3378":{"id":"n3378","loc":[-85.637409,41.949873]},"n3379":{"id":"n3379","loc":[-85.634824,41.94996]},"n338":{"id":"n338","loc":[-85.633597,41.943109]},"n3380":{"id":"n3380","loc":[-85.635437,41.949954]},"n3381":{"id":"n3381","loc":[-85.634844,41.951064]},"n3382":{"id":"n3382","loc":[-85.635458,41.951058]},"n3383":{"id":"n3383","loc":[-85.633921,41.947333]},"n3384":{"id":"n3384","loc":[-85.634208,41.947793]},"n3385":{"id":"n3385","loc":[-85.634204,41.947687]},"n3386":{"id":"n3386","loc":[-85.63424,41.947475]},"n3387":{"id":"n3387","loc":[-85.63424,41.947635]},"n3388":{"id":"n3388","loc":[-85.634089,41.948328]},"n3389":{"id":"n3389","loc":[-85.63424,41.948299]},"n339":{"id":"n339","loc":[-85.633673,41.943184]},"n3390":{"id":"n3390","loc":[-85.634239,41.948212]},"n3391":{"id":"n3391","loc":[-85.634086,41.948214]},"n3392":{"id":"n3392","loc":[-85.63408,41.948056]},"n3393":{"id":"n3393","loc":[-85.634093,41.948506]},"n3394":{"id":"n3394","loc":[-85.64344,41.941866]},"n3395":{"id":"n3395","loc":[-85.63378,41.95099]},"n3396":{"id":"n3396","loc":[-85.633779,41.950967]},"n3397":{"id":"n3397","loc":[-85.63375,41.950746]},"n3398":{"id":"n3398","loc":[-85.63375,41.950697]},"n3399":{"id":"n3399","loc":[-85.633903,41.950696]},"n34":{"id":"n34","loc":[-85.638176,41.944312]},"n340":{"id":"n340","loc":[-85.633714,41.94316]},"n3400":{"id":"n3400","loc":[-85.633901,41.950436]},"n3401":{"id":"n3401","loc":[-85.633492,41.950438]},"n3402":{"id":"n3402","loc":[-85.633494,41.950756]},"n3403":{"id":"n3403","loc":[-85.633454,41.950756]},"n3404":{"id":"n3404","loc":[-85.633456,41.950992]},"n3405":{"id":"n3405","loc":[-85.633994,41.950284]},"n3406":{"id":"n3406","loc":[-85.633998,41.950628]},"n3407":{"id":"n3407","loc":[-85.633364,41.951068]},"n3408":{"id":"n3408","loc":[-85.633356,41.949982]},"n3409":{"id":"n3409","loc":[-85.643327,41.941903]},"n341":{"id":"n341","loc":[-85.633811,41.943256]},"n3410":{"id":"n3410","loc":[-85.633292,41.953691]},"n3411":{"id":"n3411","loc":[-85.637432,41.952399]},"n3412":{"id":"n3412","loc":[-85.633349,41.957422]},"n3413":{"id":"n3413","loc":[-85.633326,41.955909]},"n3414":{"id":"n3414","loc":[-85.633307,41.954673]},"n3415":{"id":"n3415","loc":[-85.633273,41.952436]},"n3416":{"id":"n3416","loc":[-85.633361,41.95823],"tags":{"highway":"turning_circle"}},"n3417":{"id":"n3417","loc":[-85.619899,41.945527]},"n3418":{"id":"n3418","loc":[-85.643422,41.941946]},"n3419":{"id":"n3419","loc":[-85.643505,41.942033]},"n342":{"id":"n342","loc":[-85.633801,41.943261]},"n3420":{"id":"n3420","loc":[-85.620088,41.945571]},"n3421":{"id":"n3421","loc":[-85.620051,41.945505]},"n3422":{"id":"n3422","loc":[-85.62001,41.94541]},"n3423":{"id":"n3423","loc":[-85.620982,41.944742]},"n3424":{"id":"n3424","loc":[-85.621305,41.944782]},"n3425":{"id":"n3425","loc":[-85.621174,41.944819]},"n3426":{"id":"n3426","loc":[-85.621029,41.944871]},"n3427":{"id":"n3427","loc":[-85.620741,41.945011]},"n3428":{"id":"n3428","loc":[-85.620616,41.945085]},"n3429":{"id":"n3429","loc":[-85.620506,41.945172]},"n343":{"id":"n343","loc":[-85.63374,41.943514]},"n3430":{"id":"n3430","loc":[-85.620394,41.945273]},"n3431":{"id":"n3431","loc":[-85.620316,41.94536]},"n3432":{"id":"n3432","loc":[-85.620257,41.945452]},"n3433":{"id":"n3433","loc":[-85.620212,41.945535]},"n3434":{"id":"n3434","loc":[-85.620101,41.945811]},"n3435":{"id":"n3435","loc":[-85.620081,41.945937]},"n3436":{"id":"n3436","loc":[-85.619899,41.943718]},"n3437":{"id":"n3437","loc":[-85.619969,41.943211]},"n3438":{"id":"n3438","loc":[-85.619894,41.943292]},"n3439":{"id":"n3439","loc":[-85.620047,41.944738]},"n344":{"id":"n344","loc":[-85.633665,41.943441]},"n3440":{"id":"n3440","loc":[-85.620226,41.946088]},"n3441":{"id":"n3441","loc":[-85.620225,41.945864]},"n3442":{"id":"n3442","loc":[-85.620518,41.945863]},"n3443":{"id":"n3443","loc":[-85.620519,41.945944]},"n3444":{"id":"n3444","loc":[-85.620388,41.945944]},"n3445":{"id":"n3445","loc":[-85.620389,41.946088]},"n3446":{"id":"n3446","loc":[-85.618405,41.946566]},"n3447":{"id":"n3447","loc":[-85.619156,41.946562]},"n3448":{"id":"n3448","loc":[-85.619154,41.946319]},"n3449":{"id":"n3449","loc":[-85.618736,41.946322]},"n345":{"id":"n345","loc":[-85.633162,41.942947]},"n3450":{"id":"n3450","loc":[-85.618733,41.94612]},"n3451":{"id":"n3451","loc":[-85.619317,41.946116]},"n3452":{"id":"n3452","loc":[-85.619316,41.946023]},"n3453":{"id":"n3453","loc":[-85.619622,41.946021]},"n3454":{"id":"n3454","loc":[-85.619624,41.946171]},"n3455":{"id":"n3455","loc":[-85.61977,41.94617]},"n3456":{"id":"n3456","loc":[-85.619769,41.94602]},"n3457":{"id":"n3457","loc":[-85.619732,41.94602]},"n3458":{"id":"n3458","loc":[-85.619731,41.945856]},"n3459":{"id":"n3459","loc":[-85.619617,41.945857]},"n346":{"id":"n346","loc":[-85.633598,41.943083]},"n3460":{"id":"n3460","loc":[-85.619616,41.945776]},"n3461":{"id":"n3461","loc":[-85.619447,41.945777]},"n3462":{"id":"n3462","loc":[-85.619415,41.945778]},"n3463":{"id":"n3463","loc":[-85.618378,41.945788]},"n3464":{"id":"n3464","loc":[-85.618384,41.946132]},"n3465":{"id":"n3465","loc":[-85.618503,41.94613]},"n3466":{"id":"n3466","loc":[-85.618506,41.946319]},"n3467":{"id":"n3467","loc":[-85.6184,41.94632]},"n3468":{"id":"n3468","loc":[-85.618248,41.946416]},"n3469":{"id":"n3469","loc":[-85.618247,41.946319]},"n347":{"id":"n347","loc":[-85.63343,41.943179]},"n3470":{"id":"n3470","loc":[-85.618039,41.946321]},"n3471":{"id":"n3471","loc":[-85.61804,41.946418]},"n3472":{"id":"n3472","loc":[-85.620118,41.951895]},"n3473":{"id":"n3473","loc":[-85.617075,41.95469]},"n3474":{"id":"n3474","loc":[-85.620107,41.952113]},"n3475":{"id":"n3475","loc":[-85.620091,41.95232]},"n3476":{"id":"n3476","loc":[-85.620047,41.952505]},"n3477":{"id":"n3477","loc":[-85.61998,41.952715]},"n3478":{"id":"n3478","loc":[-85.619861,41.952986]},"n3479":{"id":"n3479","loc":[-85.619622,41.953365]},"n348":{"id":"n348","loc":[-85.633669,41.94341]},"n3480":{"id":"n3480","loc":[-85.619441,41.953567]},"n3481":{"id":"n3481","loc":[-85.619259,41.953741]},"n3482":{"id":"n3482","loc":[-85.618835,41.954056]},"n3483":{"id":"n3483","loc":[-85.618602,41.954194]},"n3484":{"id":"n3484","loc":[-85.618305,41.954347]},"n3485":{"id":"n3485","loc":[-85.618006,41.954466]},"n3486":{"id":"n3486","loc":[-85.617611,41.954587]},"n3487":{"id":"n3487","loc":[-85.615094,41.943412]},"n3488":{"id":"n3488","loc":[-85.619337,41.943025]},"n3489":{"id":"n3489","loc":[-85.610477,41.945527]},"n349":{"id":"n349","loc":[-85.633566,41.943466]},"n3490":{"id":"n3490","loc":[-85.610477,41.943718]},"n3491":{"id":"n3491","loc":[-85.619804,41.942976]},"n3492":{"id":"n3492","loc":[-85.61921,41.942672]},"n3493":{"id":"n3493","loc":[-85.619862,41.942836]},"n3494":{"id":"n3494","loc":[-85.616326,41.942769]},"n3495":{"id":"n3495","loc":[-85.617953,41.942917]},"n3496":{"id":"n3496","loc":[-85.61972,41.942728]},"n3497":{"id":"n3497","loc":[-85.61944,41.942784]},"n3498":{"id":"n3498","loc":[-85.615323,41.942841]},"n3499":{"id":"n3499","loc":[-85.612923,41.943718]},"n35":{"id":"n35","loc":[-85.637928,41.944249]},"n350":{"id":"n350","loc":[-85.633031,41.942986]},"n3500":{"id":"n3500","loc":[-85.61958,41.942756]},"n3501":{"id":"n3501","loc":[-85.619643,41.942647],"tags":{"leisure":"fishing"}},"n3502":{"id":"n3502","loc":[-85.619935,41.942962]},"n3503":{"id":"n3503","loc":[-85.629677,41.954687]},"n3504":{"id":"n3504","loc":[-85.629083,41.953722]},"n3505":{"id":"n3505","loc":[-85.621907,41.952067]},"n3506":{"id":"n3506","loc":[-85.621788,41.952058]},"n3507":{"id":"n3507","loc":[-85.629665,41.953718]},"n3508":{"id":"n3508","loc":[-85.624454,41.954707]},"n3509":{"id":"n3509","loc":[-85.634609,41.954585]},"n351":{"id":"n351","loc":[-85.633238,41.94283]},"n3510":{"id":"n3510","loc":[-85.634595,41.953772]},"n3511":{"id":"n3511","loc":[-85.633425,41.953783]},"n3512":{"id":"n3512","loc":[-85.633439,41.954596]},"n3517":{"id":"n3517","loc":[-85.621789,41.952179]},"n3518":{"id":"n3518","loc":[-85.624105,41.954704]},"n3519":{"id":"n3519","loc":[-85.623306,41.954542]},"n352":{"id":"n352","loc":[-85.633173,41.943556]},"n3520":{"id":"n3520","loc":[-85.623123,41.954502]},"n3521":{"id":"n3521","loc":[-85.622965,41.954473]},"n3522":{"id":"n3522","loc":[-85.622822,41.954455]},"n3523":{"id":"n3523","loc":[-85.62269,41.954448]},"n3524":{"id":"n3524","loc":[-85.622388,41.954467]},"n3525":{"id":"n3525","loc":[-85.62403,41.954895]},"n3526":{"id":"n3526","loc":[-85.623579,41.954855]},"n3527":{"id":"n3527","loc":[-85.623836,41.954951]},"n3528":{"id":"n3528","loc":[-85.622473,41.954592]},"n3529":{"id":"n3529","loc":[-85.622753,41.95458]},"n353":{"id":"n353","loc":[-85.633127,41.943552]},"n3530":{"id":"n3530","loc":[-85.62404,41.955078]},"n3531":{"id":"n3531","loc":[-85.624126,41.954999]},"n3532":{"id":"n3532","loc":[-85.623171,41.954687]},"n3533":{"id":"n3533","loc":[-85.624276,41.955206]},"n3534":{"id":"n3534","loc":[-85.62491,41.952801]},"n3535":{"id":"n3535","loc":[-85.625186,41.952756]},"n3536":{"id":"n3536","loc":[-85.625552,41.952792]},"n3537":{"id":"n3537","loc":[-85.626001,41.952948]},"n3538":{"id":"n3538","loc":[-85.626528,41.952984]},"n3539":{"id":"n3539","loc":[-85.626942,41.952886]},"n354":{"id":"n354","loc":[-85.632745,41.943222]},"n3540":{"id":"n3540","loc":[-85.627092,41.952685]},"n3541":{"id":"n3541","loc":[-85.627212,41.95244]},"n3542":{"id":"n3542","loc":[-85.627158,41.952226]},"n3543":{"id":"n3543","loc":[-85.627002,41.951972]},"n3544":{"id":"n3544","loc":[-85.626822,41.951838]},"n3545":{"id":"n3545","loc":[-85.626528,41.951807]},"n3546":{"id":"n3546","loc":[-85.625653,41.951852]},"n3547":{"id":"n3547","loc":[-85.625348,41.951834]},"n3548":{"id":"n3548","loc":[-85.625114,41.951767]},"n3549":{"id":"n3549","loc":[-85.620627,41.954682]},"n355":{"id":"n355","loc":[-85.632756,41.943199]},"n3550":{"id":"n3550","loc":[-85.622758,41.951884]},"n3551":{"id":"n3551","loc":[-85.618135,41.954734]},"n3552":{"id":"n3552","loc":[-85.620229,41.95472]},"n3553":{"id":"n3553","loc":[-85.624491,41.955573]},"n3554":{"id":"n3554","loc":[-85.621792,41.958314]},"n3555":{"id":"n3555","loc":[-85.623395,41.960001]},"n3556":{"id":"n3556","loc":[-85.620461,41.956212]},"n3557":{"id":"n3557","loc":[-85.62109,41.956766]},"n3558":{"id":"n3558","loc":[-85.620246,41.956224]},"n3559":{"id":"n3559","loc":[-85.625017,41.956068]},"n356":{"id":"n356","loc":[-85.632855,41.943147]},"n3560":{"id":"n3560","loc":[-85.622795,41.959702]},"n3561":{"id":"n3561","loc":[-85.621573,41.958457]},"n3562":{"id":"n3562","loc":[-85.619631,41.9573]},"n3563":{"id":"n3563","loc":[-85.62095,41.956311]},"n3564":{"id":"n3564","loc":[-85.619694,41.957408]},"n3565":{"id":"n3565","loc":[-85.621079,41.957751]},"n3566":{"id":"n3566","loc":[-85.622426,41.961142]},"n3567":{"id":"n3567","loc":[-85.623251,41.960484]},"n3568":{"id":"n3568","loc":[-85.619084,41.956291]},"n3569":{"id":"n3569","loc":[-85.622227,41.959303]},"n357":{"id":"n357","loc":[-85.632888,41.94315]},"n3570":{"id":"n3570","loc":[-85.620976,41.959104]},"n3571":{"id":"n3571","loc":[-85.621208,41.95653]},"n3572":{"id":"n3572","loc":[-85.623531,41.95951]},"n3573":{"id":"n3573","loc":[-85.623556,41.957935]},"n3574":{"id":"n3574","loc":[-85.623037,41.95746]},"n3575":{"id":"n3575","loc":[-85.621175,41.956427]},"n3576":{"id":"n3576","loc":[-85.622651,41.960109]},"n3577":{"id":"n3577","loc":[-85.621803,41.960747]},"n3578":{"id":"n3578","loc":[-85.620791,41.961874]},"n3579":{"id":"n3579","loc":[-85.625295,41.956786]},"n358":{"id":"n358","loc":[-85.633232,41.943547]},"n3580":{"id":"n3580","loc":[-85.619662,41.956894]},"n3581":{"id":"n3581","loc":[-85.622442,41.958708]},"n3582":{"id":"n3582","loc":[-85.621744,41.955864]},"n3583":{"id":"n3583","loc":[-85.621336,41.959212]},"n3584":{"id":"n3584","loc":[-85.622801,41.957304]},"n3585":{"id":"n3585","loc":[-85.619973,41.957433]},"n3586":{"id":"n3586","loc":[-85.619556,41.955717]},"n3587":{"id":"n3587","loc":[-85.622978,41.958601]},"n3588":{"id":"n3588","loc":[-85.625396,41.956264]},"n3589":{"id":"n3589","loc":[-85.623525,41.958034]},"n359":{"id":"n359","loc":[-85.633302,41.94351]},"n3590":{"id":"n3590","loc":[-85.623299,41.959631]},"n3591":{"id":"n3591","loc":[-85.622678,41.959873]},"n3592":{"id":"n3592","loc":[-85.625553,41.956179]},"n3593":{"id":"n3593","loc":[-85.623557,41.959231]},"n3594":{"id":"n3594","loc":[-85.622843,41.957373]},"n3595":{"id":"n3595","loc":[-85.619378,41.955677]},"n3596":{"id":"n3596","loc":[-85.620092,41.955425]},"n3597":{"id":"n3597","loc":[-85.622666,41.96044]},"n3598":{"id":"n3598","loc":[-85.621996,41.960256]},"n3599":{"id":"n3599","loc":[-85.623273,41.959997]},"n36":{"id":"n36","loc":[-85.637894,41.945551]},"n360":{"id":"n360","loc":[-85.633442,41.943794],"tags":{"highway":"crossing"}},"n3600":{"id":"n3600","loc":[-85.62477,41.95689]},"n3601":{"id":"n3601","loc":[-85.621641,41.955015]},"n3602":{"id":"n3602","loc":[-85.622495,41.960392]},"n3603":{"id":"n3603","loc":[-85.61918,41.955565]},"n3604":{"id":"n3604","loc":[-85.620017,41.955505]},"n3605":{"id":"n3605","loc":[-85.621739,41.956315]},"n3606":{"id":"n3606","loc":[-85.622957,41.959837]},"n3607":{"id":"n3607","loc":[-85.620912,41.960919]},"n3608":{"id":"n3608","loc":[-85.625231,41.956235]},"n3609":{"id":"n3609","loc":[-85.620976,41.961868]},"n361":{"id":"n361","loc":[-85.633381,41.94383]},"n3610":{"id":"n3610","loc":[-85.620956,41.958908]},"n3611":{"id":"n3611","loc":[-85.619035,41.956139]},"n3612":{"id":"n3612","loc":[-85.623643,41.958669]},"n3613":{"id":"n3613","loc":[-85.61949,41.956539]},"n3614":{"id":"n3614","loc":[-85.621927,41.958242]},"n3615":{"id":"n3615","loc":[-85.620826,41.955721]},"n3616":{"id":"n3616","loc":[-85.621202,41.961321]},"n3617":{"id":"n3617","loc":[-85.624877,41.95594]},"n3618":{"id":"n3618","loc":[-85.62065,41.958369]},"n3619":{"id":"n3619","loc":[-85.621524,41.956279]},"n362":{"id":"n362","loc":[-85.632977,41.944053]},"n3620":{"id":"n3620","loc":[-85.624662,41.955932]},"n3621":{"id":"n3621","loc":[-85.623048,41.958509]},"n3622":{"id":"n3622","loc":[-85.62111,41.95754]},"n3623":{"id":"n3623","loc":[-85.621508,41.954847]},"n3624":{"id":"n3624","loc":[-85.620655,41.958601]},"n3625":{"id":"n3625","loc":[-85.62154,41.954971]},"n3626":{"id":"n3626","loc":[-85.621691,41.955521]},"n3627":{"id":"n3627","loc":[-85.62154,41.954739]},"n3628":{"id":"n3628","loc":[-85.621996,41.959913]},"n3629":{"id":"n3629","loc":[-85.622286,41.960699]},"n363":{"id":"n363","loc":[-85.632915,41.943981],"tags":{"crossing":"zebra","highway":"crossing"}},"n3630":{"id":"n3630","loc":[-85.622844,41.9572]},"n3631":{"id":"n3631","loc":[-85.620252,41.955446]},"n3632":{"id":"n3632","loc":[-85.623434,41.957528]},"n3633":{"id":"n3633","loc":[-85.623429,41.956858]},"n3634":{"id":"n3634","loc":[-85.622957,41.957137]},"n3635":{"id":"n3635","loc":[-85.622554,41.959027]},"n3636":{"id":"n3636","loc":[-85.623289,41.958314]},"n3637":{"id":"n3637","loc":[-85.622977,41.960855]},"n3638":{"id":"n3638","loc":[-85.624008,41.956953]},"n3639":{"id":"n3639","loc":[-85.621278,41.960855]},"n364":{"id":"n364","loc":[-85.632724,41.943969],"tags":{"crossing":"zebra","highway":"crossing"}},"n3640":{"id":"n3640","loc":[-85.623128,41.956993]},"n3641":{"id":"n3641","loc":[-85.622452,41.959183]},"n3642":{"id":"n3642","loc":[-85.621095,41.961082]},"n3643":{"id":"n3643","loc":[-85.622011,41.960544]},"n3644":{"id":"n3644","loc":[-85.621637,41.955385]},"n3645":{"id":"n3645","loc":[-85.620999,41.959271]},"n3646":{"id":"n3646","loc":[-85.620044,41.956347]},"n3647":{"id":"n3647","loc":[-85.621936,41.959682]},"n3648":{"id":"n3648","loc":[-85.623761,41.95685]},"n3649":{"id":"n3649","loc":[-85.621239,41.959343]},"n365":{"id":"n365","loc":[-85.632621,41.944034]},"n3650":{"id":"n3650","loc":[-85.621073,41.956012]},"n3651":{"id":"n3651","loc":[-85.621271,41.956184]},"n3652":{"id":"n3652","loc":[-85.623444,41.95778]},"n3653":{"id":"n3653","loc":[-85.62125,41.96186]},"n3654":{"id":"n3654","loc":[-85.62169,41.961059]},"n3655":{"id":"n3655","loc":[-85.620012,41.955637]},"n3656":{"id":"n3656","loc":[-85.621058,41.9573]},"n3657":{"id":"n3657","loc":[-85.621138,41.957663]},"n3658":{"id":"n3658","loc":[-85.620773,41.957895]},"n3659":{"id":"n3659","loc":[-85.62007,41.957157]},"n366":{"id":"n366","loc":[-85.632684,41.944109],"tags":{"crossing":"zebra","highway":"crossing"}},"n3660":{"id":"n3660","loc":[-85.624534,41.955844]},"n3661":{"id":"n3661","loc":[-85.621932,41.960807]},"n3662":{"id":"n3662","loc":[-85.623358,41.958138]},"n3663":{"id":"n3663","loc":[-85.620456,41.955514]},"n3664":{"id":"n3664","loc":[-85.623504,41.957607]},"n3665":{"id":"n3665","loc":[-85.621444,41.960751]},"n3666":{"id":"n3666","loc":[-85.623492,41.960213]},"n3667":{"id":"n3667","loc":[-85.621669,41.954655]},"n3668":{"id":"n3668","loc":[-85.623106,41.958685]},"n3669":{"id":"n3669","loc":[-85.620922,41.957867]},"n367":{"id":"n367","loc":[-85.632738,41.944172]},"n3670":{"id":"n3670","loc":[-85.620092,41.957296]},"n3671":{"id":"n3671","loc":[-85.621669,41.955222]},"n3672":{"id":"n3672","loc":[-85.621614,41.960967]},"n3673":{"id":"n3673","loc":[-85.621691,41.955732]},"n3674":{"id":"n3674","loc":[-85.619207,41.956419]},"n3675":{"id":"n3675","loc":[-85.621116,41.956603]},"n3676":{"id":"n3676","loc":[-85.623311,41.956929]},"n3677":{"id":"n3677","loc":[-85.625671,41.956499]},"n3678":{"id":"n3678","loc":[-85.623525,41.956738]},"n3679":{"id":"n3679","loc":[-85.625381,41.956634]},"n368":{"id":"n368","loc":[-85.63287,41.944135],"tags":{"crossing":"zebra","highway":"crossing"}},"n3680":{"id":"n3680","loc":[-85.620096,41.95677]},"n3681":{"id":"n3681","loc":[-85.623803,41.958745]},"n3682":{"id":"n3682","loc":[-85.623498,41.958457]},"n3683":{"id":"n3683","loc":[-85.624223,41.957009]},"n3684":{"id":"n3684","loc":[-85.620026,41.956946]},"n3685":{"id":"n3685","loc":[-85.623005,41.960124]},"n3686":{"id":"n3686","loc":[-85.619073,41.955832]},"n3687":{"id":"n3687","loc":[-85.621744,41.95501]},"n3688":{"id":"n3688","loc":[-85.620804,41.958781]},"n3689":{"id":"n3689","loc":[-85.619844,41.957448]},"n369":{"id":"n369","loc":[-85.63298,41.944076]},"n3690":{"id":"n3690","loc":[-85.623713,41.958872]},"n3691":{"id":"n3691","loc":[-85.622329,41.960507]},"n3692":{"id":"n3692","loc":[-85.620804,41.956244]},"n3693":{"id":"n3693","loc":[-85.621818,41.955968]},"n3694":{"id":"n3694","loc":[-85.621405,41.958697]},"n3695":{"id":"n3695","loc":[-85.620998,41.960996]},"n3696":{"id":"n3696","loc":[-85.621621,41.960444]},"n3697":{"id":"n3697","loc":[-85.620941,41.961637]},"n3698":{"id":"n3698","loc":[-85.622195,41.958333]},"n3699":{"id":"n3699","loc":[-85.621668,41.961529]},"n37":{"id":"n37","loc":[-85.637611,41.945383]},"n370":{"id":"n370","loc":[-85.633191,41.944471]},"n3700":{"id":"n3700","loc":[-85.621015,41.957049]},"n3701":{"id":"n3701","loc":[-85.619368,41.955521]},"n3702":{"id":"n3702","loc":[-85.651578,41.942534]},"n3703":{"id":"n3703","loc":[-85.651541,41.943847]},"n3704":{"id":"n3704","loc":[-85.651365,41.944817]},"n3705":{"id":"n3705","loc":[-85.651076,41.945985]},"n3706":{"id":"n3706","loc":[-85.650626,41.947213]},"n3707":{"id":"n3707","loc":[-85.649669,41.949161]},"n3708":{"id":"n3708","loc":[-85.641802,41.961801]},"n3709":{"id":"n3709","loc":[-85.623333,41.961987]},"n371":{"id":"n371","loc":[-85.633132,41.94372]},"n3710":{"id":"n3710","loc":[-85.620621,41.965658]},"n3711":{"id":"n3711","loc":[-85.605673,41.965764]},"n3712":{"id":"n3712","loc":[-85.605664,41.962094]},"n3713":{"id":"n3713","loc":[-85.583774,41.962178]},"n3714":{"id":"n3714","loc":[-85.583774,41.961789]},"n3715":{"id":"n3715","loc":[-85.581303,41.961783]},"n3716":{"id":"n3716","loc":[-85.581245,41.958394]},"n3717":{"id":"n3717","loc":[-85.585299,41.955483]},"n3718":{"id":"n3718","loc":[-85.585588,41.955331]},"n3719":{"id":"n3719","loc":[-85.586053,41.955163]},"n372":{"id":"n372","loc":[-85.633011,41.943788]},"n3720":{"id":"n3720","loc":[-85.58632,41.955076]},"n3721":{"id":"n3721","loc":[-85.586478,41.955025]},"n3722":{"id":"n3722","loc":[-85.58692,41.954947]},"n3723":{"id":"n3723","loc":[-85.587345,41.954913]},"n3724":{"id":"n3724","loc":[-85.605592,41.954766]},"n3725":{"id":"n3725","loc":[-85.605303,41.936236]},"n3726":{"id":"n3726","loc":[-85.606941,41.936117]},"n3727":{"id":"n3727","loc":[-85.60876,41.935856]},"n3728":{"id":"n3728","loc":[-85.610092,41.935451]},"n3729":{"id":"n3729","loc":[-85.610681,41.935247]},"n373":{"id":"n373","loc":[-85.632854,41.943632]},"n3730":{"id":"n3730","loc":[-85.611446,41.934955]},"n3731":{"id":"n3731","loc":[-85.612057,41.934696]},"n3732":{"id":"n3732","loc":[-85.613256,41.934084]},"n3733":{"id":"n3733","loc":[-85.613948,41.933682]},"n3734":{"id":"n3734","loc":[-85.614638,41.933212]},"n3735":{"id":"n3735","loc":[-85.619801,41.929305]},"n3736":{"id":"n3736","loc":[-85.619768,41.925548]},"n3737":{"id":"n3737","loc":[-85.625761,41.925597]},"n3738":{"id":"n3738","loc":[-85.6263,41.927323]},"n3739":{"id":"n3739","loc":[-85.633708,41.927402]},"n374":{"id":"n374","loc":[-85.632974,41.943565]},"n3740":{"id":"n3740","loc":[-85.633927,41.929109]},"n3741":{"id":"n3741","loc":[-85.639213,41.929088]},"n3742":{"id":"n3742","loc":[-85.639204,41.925488]},"n3743":{"id":"n3743","loc":[-85.651425,41.925406]},"n3744":{"id":"n3744","loc":[-85.643386,41.941933]},"n3745":{"id":"n3745","loc":[-85.642776,41.941161]},"n3746":{"id":"n3746","loc":[-85.637277,41.948812]},"n3747":{"id":"n3747","loc":[-85.637366,41.94897]},"n3748":{"id":"n3748","loc":[-85.637329,41.94889]},"n3749":{"id":"n3749","loc":[-85.629649,41.952596]},"n375":{"id":"n375","loc":[-85.632741,41.943351]},"n3750":{"id":"n3750","loc":[-85.630291,41.954684]},"n3751":{"id":"n3751","loc":[-85.630284,41.953713]},"n3752":{"id":"n3752","loc":[-85.630269,41.952463]},"n3753":{"id":"n3753","loc":[-85.633933,41.949896]},"n3754":{"id":"n3754","loc":[-85.629339,41.941467]},"n3755":{"id":"n3755","loc":[-85.629857,41.94316]},"n3756":{"id":"n3756","loc":[-85.629987,41.944025]},"n3757":{"id":"n3757","loc":[-85.628538,41.948604]},"n3758":{"id":"n3758","loc":[-85.627415,41.957442]},"n3759":{"id":"n3759","loc":[-85.627019,41.957369]},"n376":{"id":"n376","loc":[-85.63251,41.943481]},"n3760":{"id":"n3760","loc":[-85.62167,41.952179]},"n3761":{"id":"n3761","loc":[-85.62167,41.952138]},"n3762":{"id":"n3762","loc":[-85.621562,41.952139]},"n3763":{"id":"n3763","loc":[-85.621562,41.952058]},"n3764":{"id":"n3764","loc":[-85.621476,41.952043]},"n3765":{"id":"n3765","loc":[-85.621477,41.952132]},"n3766":{"id":"n3766","loc":[-85.621386,41.952132]},"n3767":{"id":"n3767","loc":[-85.621387,41.95214]},"n3768":{"id":"n3768","loc":[-85.621262,41.95214]},"n3769":{"id":"n3769","loc":[-85.621261,41.952038]},"n377":{"id":"n377","loc":[-85.632706,41.943715]},"n3770":{"id":"n3770","loc":[-85.621389,41.952038]},"n3771":{"id":"n3771","loc":[-85.621389,41.952043]},"n3772":{"id":"n3772","loc":[-85.620898,41.952024]},"n3773":{"id":"n3773","loc":[-85.620898,41.952085]},"n3774":{"id":"n3774","loc":[-85.620774,41.952084]},"n3775":{"id":"n3775","loc":[-85.620774,41.952023]},"n3776":{"id":"n3776","loc":[-85.620749,41.952036]},"n3777":{"id":"n3777","loc":[-85.620723,41.952097]},"n3778":{"id":"n3778","loc":[-85.626158,41.958996]},"n3779":{"id":"n3779","loc":[-85.626319,41.958686]},"n378":{"id":"n378","loc":[-85.638683,41.943295]},"n3780":{"id":"n3780","loc":[-85.626119,41.958629]},"n3781":{"id":"n3781","loc":[-85.626064,41.958733]},"n3782":{"id":"n3782","loc":[-85.626155,41.958759]},"n3783":{"id":"n3783","loc":[-85.626048,41.958965]},"n3784":{"id":"n3784","loc":[-85.620648,41.952079]},"n3785":{"id":"n3785","loc":[-85.63826,41.961213]},"n3786":{"id":"n3786","loc":[-85.638003,41.961614]},"n3787":{"id":"n3787","loc":[-85.638817,41.961902]},"n3788":{"id":"n3788","loc":[-85.639073,41.961501]},"n3789":{"id":"n3789","loc":[-85.620674,41.952018]},"n379":{"id":"n379","loc":[-85.638684,41.94323]},"n3790":{"id":"n3790","loc":[-85.62082,41.952106]},"n3791":{"id":"n3791","loc":[-85.620819,41.952143]},"n3792":{"id":"n3792","loc":[-85.620778,41.952143]},"n3793":{"id":"n3793","loc":[-85.620778,41.952106]},"n3794":{"id":"n3794","loc":[-85.620563,41.952276]},"n3795":{"id":"n3795","loc":[-85.620543,41.95238]},"n3796":{"id":"n3796","loc":[-85.620422,41.952367]},"n3797":{"id":"n3797","loc":[-85.620441,41.952263]},"n3798":{"id":"n3798","loc":[-85.620561,41.952266]},"n3799":{"id":"n3799","loc":[-85.620444,41.952254]},"n38":{"id":"n38","loc":[-85.63879,41.943295]},"n380":{"id":"n380","loc":[-85.638627,41.94322]},"n3800":{"id":"n3800","loc":[-85.620773,41.955585]},"n3801":{"id":"n3801","loc":[-85.621265,41.955989]},"n3802":{"id":"n3802","loc":[-85.620692,41.954969]},"n3803":{"id":"n3803","loc":[-85.620691,41.955367]},"n3804":{"id":"n3804","loc":[-85.620458,41.952178]},"n3805":{"id":"n3805","loc":[-85.620575,41.95219]},"n3806":{"id":"n3806","loc":[-85.617609,41.952712]},"n3807":{"id":"n3807","loc":[-85.617533,41.952801],"tags":{"entrance":"yes"}},"n3808":{"id":"n3808","loc":[-85.616816,41.952911]},"n3809":{"id":"n3809","loc":[-85.616797,41.952901]},"n381":{"id":"n381","loc":[-85.638624,41.943294]},"n3810":{"id":"n3810","loc":[-85.616343,41.952694]},"n3811":{"id":"n3811","loc":[-85.616336,41.952729]},"n3812":{"id":"n3812","loc":[-85.616343,41.952772]},"n3813":{"id":"n3813","loc":[-85.628479,41.948649]},"n3814":{"id":"n3814","loc":[-85.628413,41.948679]},"n3815":{"id":"n3815","loc":[-85.628336,41.948694]},"n3816":{"id":"n3816","loc":[-85.62826,41.948694]},"n3817":{"id":"n3817","loc":[-85.628185,41.948679]},"n3818":{"id":"n3818","loc":[-85.628103,41.948649]},"n3819":{"id":"n3819","loc":[-85.627482,41.948395]},"n382":{"id":"n382","loc":[-85.638437,41.943291]},"n3820":{"id":"n3820","loc":[-85.619957,41.951168]},"n3821":{"id":"n3821","loc":[-85.619955,41.952077]},"n3822":{"id":"n3822","loc":[-85.619843,41.952666]},"n3823":{"id":"n3823","loc":[-85.619513,41.95324]},"n3824":{"id":"n3824","loc":[-85.619163,41.953668]},"n3825":{"id":"n3825","loc":[-85.618813,41.953947]},"n3826":{"id":"n3826","loc":[-85.618265,41.954252]},"n3827":{"id":"n3827","loc":[-85.617691,41.954458]},"n3828":{"id":"n3828","loc":[-85.616978,41.95459]},"n3829":{"id":"n3829","loc":[-85.615408,41.954628]},"n383":{"id":"n383","loc":[-85.63844,41.943209]},"n3830":{"id":"n3830","loc":[-85.615374,41.951076]},"n3831":{"id":"n3831","loc":[-85.61932,41.947564]},"n3832":{"id":"n3832","loc":[-85.610553,41.94755]},"n3833":{"id":"n3833","loc":[-85.610572,41.951065]},"n3834":{"id":"n3834","loc":[-85.617548,41.94757]},"n3835":{"id":"n3835","loc":[-85.619842,41.947939]},"n3836":{"id":"n3836","loc":[-85.619874,41.950905]},"n3837":{"id":"n3837","loc":[-85.619695,41.950911]},"n3838":{"id":"n3838","loc":[-85.617591,41.951078]},"n3839":{"id":"n3839","loc":[-85.619551,41.951065]},"n384":{"id":"n384","loc":[-85.632616,41.944021]},"n3840":{"id":"n3840","loc":[-85.626813,41.947337]},"n3841":{"id":"n3841","loc":[-85.616371,41.952814]},"n3842":{"id":"n3842","loc":[-85.617205,41.951308]},"n3843":{"id":"n3843","loc":[-85.616795,41.950953]},"n3844":{"id":"n3844","loc":[-85.617441,41.950889]},"n3845":{"id":"n3845","loc":[-85.619155,41.949377]},"n3846":{"id":"n3846","loc":[-85.618556,41.949377]},"n3847":{"id":"n3847","loc":[-85.618557,41.948372]},"n3848":{"id":"n3848","loc":[-85.619156,41.948372]},"n3849":{"id":"n3849","loc":[-85.61927,41.949796]},"n385":{"id":"n385","loc":[-85.632319,41.944172]},"n3850":{"id":"n3850","loc":[-85.61926,41.948344]},"n3851":{"id":"n3851","loc":[-85.619219,41.948264]},"n3852":{"id":"n3852","loc":[-85.619147,41.948196]},"n3853":{"id":"n3853","loc":[-85.619049,41.948144]},"n3854":{"id":"n3854","loc":[-85.618942,41.948116]},"n3855":{"id":"n3855","loc":[-85.618822,41.948109]},"n3856":{"id":"n3856","loc":[-85.618699,41.94813]},"n3857":{"id":"n3857","loc":[-85.618937,41.951943]},"n3858":{"id":"n3858","loc":[-85.616755,41.952231]},"n3859":{"id":"n3859","loc":[-85.616799,41.95472]},"n386":{"id":"n386","loc":[-85.63221,41.944066]},"n3860":{"id":"n3860","loc":[-85.616458,41.954735]},"n3861":{"id":"n3861","loc":[-85.61763,41.951515]},"n3862":{"id":"n3862","loc":[-85.617735,41.951572]},"n3863":{"id":"n3863","loc":[-85.61929,41.951573]},"n3864":{"id":"n3864","loc":[-85.617134,41.951348]},"n3865":{"id":"n3865","loc":[-85.616598,41.95192]},"n3866":{"id":"n3866","loc":[-85.616572,41.951992]},"n3867":{"id":"n3867","loc":[-85.616583,41.952076]},"n3868":{"id":"n3868","loc":[-85.616636,41.952145]},"n3869":{"id":"n3869","loc":[-85.616916,41.952279]},"n387":{"id":"n387","loc":[-85.632524,41.943912]},"n3870":{"id":"n3870","loc":[-85.617088,41.952254]},"n3871":{"id":"n3871","loc":[-85.61892,41.951467]},"n3872":{"id":"n3872","loc":[-85.618035,41.951473]},"n3873":{"id":"n3873","loc":[-85.618036,41.951572]},"n3874":{"id":"n3874","loc":[-85.61892,41.951573]},"n3875":{"id":"n3875","loc":[-85.618919,41.951957]},"n3876":{"id":"n3876","loc":[-85.619457,41.952237]},"n3877":{"id":"n3877","loc":[-85.618178,41.953618]},"n3878":{"id":"n3878","loc":[-85.617658,41.953366]},"n3879":{"id":"n3879","loc":[-85.617987,41.953024]},"n388":{"id":"n388","loc":[-85.632268,41.943621]},"n3880":{"id":"n3880","loc":[-85.618429,41.953248]},"n3881":{"id":"n3881","loc":[-85.618554,41.953119]},"n3882":{"id":"n3882","loc":[-85.618077,41.952868]},"n3883":{"id":"n3883","loc":[-85.618039,41.952886]},"n3884":{"id":"n3884","loc":[-85.619375,41.952169]},"n3885":{"id":"n3885","loc":[-85.618137,41.953538]},"n3886":{"id":"n3886","loc":[-85.61799,41.953555]},"n3887":{"id":"n3887","loc":[-85.617729,41.953423]},"n3888":{"id":"n3888","loc":[-85.618101,41.953029]},"n3889":{"id":"n3889","loc":[-85.618516,41.953119]},"n389":{"id":"n389","loc":[-85.631951,41.943773]},"n3890":{"id":"n3890","loc":[-85.619132,41.952042]},"n3891":{"id":"n3891","loc":[-85.618235,41.952981]},"n3892":{"id":"n3892","loc":[-85.618485,41.952425]},"n3893":{"id":"n3893","loc":[-85.618676,41.952519]},"n3894":{"id":"n3894","loc":[-85.618942,41.952648]},"n3895":{"id":"n3895","loc":[-85.618287,41.953122]},"n3896":{"id":"n3896","loc":[-85.617914,41.953516]},"n3897":{"id":"n3897","loc":[-85.617836,41.953573]},"n3898":{"id":"n3898","loc":[-85.616477,41.95289]},"n3899":{"id":"n3899","loc":[-85.618441,41.953201]},"n39":{"id":"n39","loc":[-85.619931,41.951013]},"n390":{"id":"n390","loc":[-85.631981,41.943654]},"n3900":{"id":"n3900","loc":[-85.617537,41.953335]},"n3901":{"id":"n3901","loc":[-85.617221,41.953166]},"n3902":{"id":"n3902","loc":[-85.617253,41.953135]},"n3903":{"id":"n3903","loc":[-85.617211,41.953114]},"n3904":{"id":"n3904","loc":[-85.617197,41.95313]},"n3905":{"id":"n3905","loc":[-85.616802,41.952925]},"n3906":{"id":"n3906","loc":[-85.616771,41.952928]},"n3907":{"id":"n3907","loc":[-85.616493,41.952785]},"n3908":{"id":"n3908","loc":[-85.616823,41.952426]},"n3909":{"id":"n3909","loc":[-85.617191,41.952616]},"n391":{"id":"n391","loc":[-85.631886,41.943699]},"n3910":{"id":"n3910","loc":[-85.61724,41.952559]},"n3911":{"id":"n3911","loc":[-85.61721,41.952542]},"n3912":{"id":"n3912","loc":[-85.617395,41.952351]},"n3913":{"id":"n3913","loc":[-85.617426,41.952368]},"n3914":{"id":"n3914","loc":[-85.617483,41.952309]},"n3915":{"id":"n3915","loc":[-85.617332,41.952229]},"n3916":{"id":"n3916","loc":[-85.617451,41.952102]},"n3917":{"id":"n3917","loc":[-85.617477,41.952115]},"n3918":{"id":"n3918","loc":[-85.617658,41.951923]},"n3919":{"id":"n3919","loc":[-85.617634,41.95191]},"n392":{"id":"n392","loc":[-85.631807,41.943606]},"n3920":{"id":"n3920","loc":[-85.617747,41.951786]},"n3921":{"id":"n3921","loc":[-85.618268,41.952056]},"n3922":{"id":"n3922","loc":[-85.618211,41.952122]},"n3923":{"id":"n3923","loc":[-85.618386,41.95222]},"n3924":{"id":"n3924","loc":[-85.618098,41.952527]},"n3925":{"id":"n3925","loc":[-85.617916,41.95243]},"n3926":{"id":"n3926","loc":[-85.617854,41.952498]},"n3927":{"id":"n3927","loc":[-85.617769,41.952453]},"n3928":{"id":"n3928","loc":[-85.617476,41.952773]},"n3929":{"id":"n3929","loc":[-85.617876,41.952973]},"n393":{"id":"n393","loc":[-85.631902,41.943561]},"n3930":{"id":"n3930","loc":[-85.617174,41.953638]},"n3931":{"id":"n3931","loc":[-85.618016,41.953578]},"n3932":{"id":"n3932","loc":[-85.618107,41.953628]},"n3933":{"id":"n3933","loc":[-85.618067,41.954268]},"n3934":{"id":"n3934","loc":[-85.617864,41.954263]},"n3935":{"id":"n3935","loc":[-85.61762,41.954205]},"n3936":{"id":"n3936","loc":[-85.617437,41.954103]},"n3937":{"id":"n3937","loc":[-85.617294,41.953978]},"n3938":{"id":"n3938","loc":[-85.617217,41.95384]},"n3939":{"id":"n3939","loc":[-85.616814,41.954327]},"n394":{"id":"n394","loc":[-85.63236,41.943543]},"n3940":{"id":"n3940","loc":[-85.616778,41.95381]},"n3941":{"id":"n3941","loc":[-85.616585,41.953707]},"n3942":{"id":"n3942","loc":[-85.616458,41.954318]},"n3943":{"id":"n3943","loc":[-85.616643,41.954345]},"n3944":{"id":"n3944","loc":[-85.618133,41.951412]},"n3945":{"id":"n3945","loc":[-85.618326,41.951411]},"n3946":{"id":"n3946","loc":[-85.618503,41.95141]},"n3947":{"id":"n3947","loc":[-85.618681,41.951409]},"n3948":{"id":"n3948","loc":[-85.618868,41.951408]},"n3949":{"id":"n3949","loc":[-85.617047,41.95136]},"n395":{"id":"n395","loc":[-85.633839,41.944082]},"n3950":{"id":"n3950","loc":[-85.616494,41.951959]},"n3951":{"id":"n3951","loc":[-85.616497,41.952072]},"n3952":{"id":"n3952","loc":[-85.616565,41.952165]},"n3953":{"id":"n3953","loc":[-85.616663,41.952218]},"n3954":{"id":"n3954","loc":[-85.616733,41.952255]},"n3955":{"id":"n3955","loc":[-85.617238,41.952512],"tags":{"entrance":"yes"}},"n3956":{"id":"n3956","loc":[-85.617043,41.952406]},"n3957":{"id":"n3957","loc":[-85.617691,41.951711]},"n3958":{"id":"n3958","loc":[-85.617773,41.951679]},"n3959":{"id":"n3959","loc":[-85.619085,41.951681]},"n396":{"id":"n396","loc":[-85.63376,41.944097]},"n3960":{"id":"n3960","loc":[-85.617943,41.952895]},"n3961":{"id":"n3961","loc":[-85.618039,41.952938]},"n3962":{"id":"n3962","loc":[-85.61763,41.95336]},"n3963":{"id":"n3963","loc":[-85.617554,41.95344]},"n3964":{"id":"n3964","loc":[-85.617381,41.952366],"tags":{"entrance":"yes"}},"n3965":{"id":"n3965","loc":[-85.617184,41.952254]},"n3966":{"id":"n3966","loc":[-85.617208,41.952496]},"n3967":{"id":"n3967","loc":[-85.617124,41.952581],"tags":{"entrance":"yes"}},"n3968":{"id":"n3968","loc":[-85.618094,41.952735]},"n3969":{"id":"n3969","loc":[-85.617702,41.952525],"tags":{"entrance":"yes"}},"n397":{"id":"n397","loc":[-85.63361,41.943957]},"n3970":{"id":"n3970","loc":[-85.617554,41.952686],"tags":{"entrance":"yes"}},"n3971":{"id":"n3971","loc":[-85.617959,41.952878]},"n3972":{"id":"n3972","loc":[-85.616367,41.952655]},"n3973":{"id":"n3973","loc":[-85.616416,41.952851]},"n3974":{"id":"n3974","loc":[-85.619777,41.951075]},"n3975":{"id":"n3975","loc":[-85.618611,41.94817]},"n3976":{"id":"n3976","loc":[-85.618538,41.948229]},"n3977":{"id":"n3977","loc":[-85.617421,41.947559]},"n3978":{"id":"n3978","loc":[-85.617395,41.951039]},"n3979":{"id":"n3979","loc":[-85.618488,41.94829]},"n398":{"id":"n398","loc":[-85.633309,41.943886]},"n3980":{"id":"n3980","loc":[-85.610238,41.954774]},"n3981":{"id":"n3981","loc":[-85.617449,41.950756]},"n3982":{"id":"n3982","loc":[-85.617288,41.951286]},"n3983":{"id":"n3983","loc":[-85.61745,41.950197]},"n3984":{"id":"n3984","loc":[-85.617436,41.948908]},"n3985":{"id":"n3985","loc":[-85.615915,41.953804]},"n3986":{"id":"n3986","loc":[-85.615953,41.953968]},"n3987":{"id":"n3987","loc":[-85.616031,41.954085]},"n3988":{"id":"n3988","loc":[-85.616135,41.954181]},"n3989":{"id":"n3989","loc":[-85.616273,41.954263]},"n399":{"id":"n399","loc":[-85.633226,41.943931]},"n3990":{"id":"n3990","loc":[-85.618327,41.951083]},"n3991":{"id":"n3991","loc":[-85.618135,41.951084]},"n3992":{"id":"n3992","loc":[-85.618503,41.951082]},"n3993":{"id":"n3993","loc":[-85.618682,41.951081]},"n3994":{"id":"n3994","loc":[-85.618864,41.951082]},"n3995":{"id":"n3995","loc":[-85.616761,41.950101]},"n3996":{"id":"n3996","loc":[-85.617317,41.947558]},"n3997":{"id":"n3997","loc":[-85.617336,41.948883]},"n3998":{"id":"n3998","loc":[-85.616779,41.949295]},"n3999":{"id":"n3999","loc":[-85.616754,41.949349]},"n4":{"id":"n4","loc":[-85.622764,41.950892],"tags":{"highway":"stop"}},"n40":{"id":"n40","loc":[-85.619841,41.951037]},"n400":{"id":"n400","loc":[-85.63326,41.943966]},"n4000":{"id":"n4000","loc":[-85.616761,41.950865]},"n4001":{"id":"n4001","loc":[-85.616883,41.951041]},"n4002":{"id":"n4002","loc":[-85.617004,41.951142]},"n4003":{"id":"n4003","loc":[-85.617062,41.951248]},"n4004":{"id":"n4004","loc":[-85.616809,41.949273]},"n4005":{"id":"n4005","loc":[-85.616755,41.949489]},"n4006":{"id":"n4006","loc":[-85.616759,41.949971]},"n4007":{"id":"n4007","loc":[-85.616757,41.949702]},"n4008":{"id":"n4008","loc":[-85.618456,41.94836]},"n4009":{"id":"n4009","loc":[-85.618447,41.948428]},"n401":{"id":"n401","loc":[-85.63324,41.943976]},"n4010":{"id":"n4010","loc":[-85.618437,41.949322]},"n4011":{"id":"n4011","loc":[-85.618447,41.949418]},"n4012":{"id":"n4012","loc":[-85.618478,41.949491]},"n4013":{"id":"n4013","loc":[-85.618535,41.949559]},"n4014":{"id":"n4014","loc":[-85.618623,41.94962]},"n4015":{"id":"n4015","loc":[-85.618721,41.94966]},"n4016":{"id":"n4016","loc":[-85.618838,41.949674]},"n4017":{"id":"n4017","loc":[-85.618967,41.949667]},"n4018":{"id":"n4018","loc":[-85.619065,41.949632]},"n4019":{"id":"n4019","loc":[-85.61915,41.949578]},"n402":{"id":"n402","loc":[-85.63327,41.944006]},"n4020":{"id":"n4020","loc":[-85.619216,41.949507]},"n4021":{"id":"n4021","loc":[-85.61927,41.949399]},"n4022":{"id":"n4022","loc":[-85.619074,41.947639]},"n4023":{"id":"n4023","loc":[-85.619073,41.947793]},"n4024":{"id":"n4024","loc":[-85.618912,41.947793]},"n4025":{"id":"n4025","loc":[-85.618911,41.947947]},"n4026":{"id":"n4026","loc":[-85.618752,41.947947]},"n4027":{"id":"n4027","loc":[-85.618754,41.947637]},"n4028":{"id":"n4028","loc":[-85.617896,41.947599]},"n4029":{"id":"n4029","loc":[-85.617898,41.947811]},"n403":{"id":"n403","loc":[-85.633278,41.944002]},"n4030":{"id":"n4030","loc":[-85.617717,41.947812]},"n4031":{"id":"n4031","loc":[-85.617715,41.9476]},"n4032":{"id":"n4032","loc":[-85.619003,41.949828]},"n4033":{"id":"n4033","loc":[-85.619003,41.949882]},"n4034":{"id":"n4034","loc":[-85.618926,41.949882]},"n4035":{"id":"n4035","loc":[-85.618926,41.949828]},"n4036":{"id":"n4036","loc":[-85.618861,41.949809]},"n4037":{"id":"n4037","loc":[-85.618861,41.949898]},"n4038":{"id":"n4038","loc":[-85.618688,41.949898]},"n4039":{"id":"n4039","loc":[-85.618687,41.94981]},"n404":{"id":"n404","loc":[-85.63331,41.944036]},"n4040":{"id":"n4040","loc":[-85.618349,41.949473]},"n4041":{"id":"n4041","loc":[-85.618287,41.949473]},"n4042":{"id":"n4042","loc":[-85.618287,41.94942]},"n4043":{"id":"n4043","loc":[-85.618348,41.949419]},"n4044":{"id":"n4044","loc":[-85.62316,41.951604]},"n4045":{"id":"n4045","loc":[-85.623026,41.951605]},"n4046":{"id":"n4046","loc":[-85.623023,41.951466]},"n4047":{"id":"n4047","loc":[-85.623134,41.951465]},"n4048":{"id":"n4048","loc":[-85.623136,41.951539]},"n4049":{"id":"n4049","loc":[-85.623159,41.951539]},"n405":{"id":"n405","loc":[-85.633348,41.944015]},"n4050":{"id":"n4050","loc":[-85.623025,41.95155]},"n4051":{"id":"n4051","loc":[-85.622955,41.951551]},"n4052":{"id":"n4052","loc":[-85.622953,41.951507]},"n4053":{"id":"n4053","loc":[-85.623024,41.951506]},"n4054":{"id":"n4054","loc":[-85.623318,41.951242]},"n4055":{"id":"n4055","loc":[-85.623175,41.951241]},"n4056":{"id":"n4056","loc":[-85.623176,41.951153]},"n4057":{"id":"n4057","loc":[-85.623319,41.951154]},"n4058":{"id":"n4058","loc":[-85.623077,41.951191]},"n4059":{"id":"n4059","loc":[-85.622973,41.951191]},"n406":{"id":"n406","loc":[-85.63338,41.944048]},"n4060":{"id":"n4060","loc":[-85.622972,41.951349]},"n4061":{"id":"n4061","loc":[-85.623059,41.95135]},"n4062":{"id":"n4062","loc":[-85.62306,41.951301]},"n4063":{"id":"n4063","loc":[-85.623077,41.951301]},"n4064":{"id":"n4064","loc":[-85.623117,41.951405]},"n4065":{"id":"n4065","loc":[-85.62312,41.951087]},"n4066":{"id":"n4066","loc":[-85.623118,41.951274]},"n4067":{"id":"n4067","loc":[-85.62328,41.951275]},"n4068":{"id":"n4068","loc":[-85.62328,41.951242]},"n4069":{"id":"n4069","loc":[-85.623179,41.951392]},"n407":{"id":"n407","loc":[-85.633431,41.94402]},"n4070":{"id":"n4070","loc":[-85.623141,41.951392]},"n4071":{"id":"n4071","loc":[-85.623142,41.95136]},"n4072":{"id":"n4072","loc":[-85.623179,41.951361]},"n4073":{"id":"n4073","loc":[-85.622565,41.951639]},"n4074":{"id":"n4074","loc":[-85.622565,41.951741]},"n4075":{"id":"n4075","loc":[-85.622463,41.95174]},"n4076":{"id":"n4076","loc":[-85.622463,41.95173]},"n4077":{"id":"n4077","loc":[-85.622442,41.95173]},"n4078":{"id":"n4078","loc":[-85.622442,41.951742]},"n4079":{"id":"n4079","loc":[-85.622361,41.951742]},"n408":{"id":"n408","loc":[-85.633425,41.944014]},"n4080":{"id":"n4080","loc":[-85.622362,41.951667]},"n4081":{"id":"n4081","loc":[-85.622441,41.951667]},"n4082":{"id":"n4082","loc":[-85.622441,41.951688]},"n4083":{"id":"n4083","loc":[-85.622461,41.951688]},"n4084":{"id":"n4084","loc":[-85.622461,41.951638]},"n4085":{"id":"n4085","loc":[-85.62255,41.951587]},"n4086":{"id":"n4086","loc":[-85.622449,41.95159]},"n4087":{"id":"n4087","loc":[-85.622441,41.951448]},"n4088":{"id":"n4088","loc":[-85.62253,41.951445]},"n4089":{"id":"n4089","loc":[-85.622532,41.951486]},"n409":{"id":"n409","loc":[-85.633457,41.943997]},"n4090":{"id":"n4090","loc":[-85.622555,41.951485]},"n4091":{"id":"n4091","loc":[-85.622558,41.951531]},"n4092":{"id":"n4092","loc":[-85.622547,41.951531]},"n4093":{"id":"n4093","loc":[-85.622451,41.95159]},"n4094":{"id":"n4094","loc":[-85.622452,41.95161]},"n4095":{"id":"n4095","loc":[-85.622106,41.951617]},"n4096":{"id":"n4096","loc":[-85.622133,41.951443]},"n4097":{"id":"n4097","loc":[-85.622552,41.951379]},"n4098":{"id":"n4098","loc":[-85.622443,41.95138]},"n4099":{"id":"n4099","loc":[-85.622441,41.951281]},"n41":{"id":"n41","loc":[-85.636233,41.942764]},"n410":{"id":"n410","loc":[-85.633429,41.943969]},"n4100":{"id":"n4100","loc":[-85.62255,41.95128]},"n4101":{"id":"n4101","loc":[-85.622541,41.951437]},"n4102":{"id":"n4102","loc":[-85.622441,41.951438]},"n4103":{"id":"n4103","loc":[-85.621561,41.951444]},"n4104":{"id":"n4104","loc":[-85.622302,41.951479]},"n4105":{"id":"n4105","loc":[-85.6223,41.95152]},"n4106":{"id":"n4106","loc":[-85.622169,41.951517]},"n4107":{"id":"n4107","loc":[-85.622171,41.951476]},"n4108":{"id":"n4108","loc":[-85.622543,41.951228]},"n4109":{"id":"n4109","loc":[-85.622433,41.951228]},"n411":{"id":"n411","loc":[-85.633442,41.943962]},"n4110":{"id":"n4110","loc":[-85.622433,41.951133]},"n4111":{"id":"n4111","loc":[-85.622543,41.951133]},"n4112":{"id":"n4112","loc":[-85.622356,41.951256]},"n4113":{"id":"n4113","loc":[-85.622293,41.951256]},"n4114":{"id":"n4114","loc":[-85.622292,41.9512]},"n4115":{"id":"n4115","loc":[-85.622313,41.9512]},"n4116":{"id":"n4116","loc":[-85.622312,41.951173]},"n4117":{"id":"n4117","loc":[-85.622364,41.951173]},"n4118":{"id":"n4118","loc":[-85.622365,41.951231]},"n4119":{"id":"n4119","loc":[-85.622355,41.951231]},"n412":{"id":"n412","loc":[-85.633411,41.943932]},"n4120":{"id":"n4120","loc":[-85.62197,41.951155]},"n4121":{"id":"n4121","loc":[-85.62197,41.951213]},"n4122":{"id":"n4122","loc":[-85.621848,41.951213]},"n4123":{"id":"n4123","loc":[-85.621848,41.951155]},"n4124":{"id":"n4124","loc":[-85.622193,41.951268]},"n4125":{"id":"n4125","loc":[-85.622194,41.951305]},"n4126":{"id":"n4126","loc":[-85.622121,41.951306]},"n4127":{"id":"n4127","loc":[-85.622121,41.951322]},"n4128":{"id":"n4128","loc":[-85.621984,41.951324]},"n4129":{"id":"n4129","loc":[-85.621983,41.951271]},"n413":{"id":"n413","loc":[-85.633421,41.943926]},"n4130":{"id":"n4130","loc":[-85.622171,41.9514]},"n4131":{"id":"n4131","loc":[-85.622148,41.951382]},"n4132":{"id":"n4132","loc":[-85.6221,41.951414]},"n4133":{"id":"n4133","loc":[-85.622122,41.951433]},"n4134":{"id":"n4134","loc":[-85.621782,41.951148]},"n4135":{"id":"n4135","loc":[-85.621783,41.951219]},"n4136":{"id":"n4136","loc":[-85.62164,41.951221]},"n4137":{"id":"n4137","loc":[-85.62164,41.951236]},"n4138":{"id":"n4138","loc":[-85.621556,41.951237]},"n4139":{"id":"n4139","loc":[-85.621555,41.95117]},"n414":{"id":"n414","loc":[-85.633376,41.94388]},"n4140":{"id":"n4140","loc":[-85.621644,41.951169]},"n4141":{"id":"n4141","loc":[-85.621643,41.951139]},"n4142":{"id":"n4142","loc":[-85.621719,41.951138]},"n4143":{"id":"n4143","loc":[-85.621719,41.951148]},"n4144":{"id":"n4144","loc":[-85.621409,41.951322]},"n4145":{"id":"n4145","loc":[-85.621338,41.951322]},"n4146":{"id":"n4146","loc":[-85.621336,41.95115]},"n4147":{"id":"n4147","loc":[-85.621521,41.951149]},"n4148":{"id":"n4148","loc":[-85.621522,41.951228]},"n4149":{"id":"n4149","loc":[-85.621408,41.951228]},"n415":{"id":"n415","loc":[-85.633348,41.943895]},"n4150":{"id":"n4150","loc":[-85.621284,41.951219]},"n4151":{"id":"n4151","loc":[-85.621153,41.951219]},"n4152":{"id":"n4152","loc":[-85.621152,41.951152]},"n4153":{"id":"n4153","loc":[-85.621283,41.951152]},"n4154":{"id":"n4154","loc":[-85.621159,41.951241]},"n4155":{"id":"n4155","loc":[-85.62116,41.951301]},"n4156":{"id":"n4156","loc":[-85.621088,41.951302]},"n4157":{"id":"n4157","loc":[-85.621088,41.951241]},"n4158":{"id":"n4158","loc":[-85.621049,41.951158]},"n4159":{"id":"n4159","loc":[-85.62105,41.951229]},"n416":{"id":"n416","loc":[-85.633341,41.943888]},"n4160":{"id":"n4160","loc":[-85.620976,41.951229]},"n4161":{"id":"n4161","loc":[-85.620977,41.951295]},"n4162":{"id":"n4162","loc":[-85.620887,41.951296]},"n4163":{"id":"n4163","loc":[-85.620886,41.951229]},"n4164":{"id":"n4164","loc":[-85.620862,41.951229]},"n4165":{"id":"n4165","loc":[-85.620861,41.951159]},"n4166":{"id":"n4166","loc":[-85.620626,41.951133]},"n4167":{"id":"n4167","loc":[-85.620626,41.951205]},"n4168":{"id":"n4168","loc":[-85.620412,41.951206]},"n4169":{"id":"n4169","loc":[-85.620411,41.951134]},"n417":{"id":"n417","loc":[-85.633321,41.943898]},"n4170":{"id":"n4170","loc":[-85.621775,41.951443]},"n4171":{"id":"n4171","loc":[-85.621777,41.951264]},"n4172":{"id":"n4172","loc":[-85.621565,41.951654]},"n4173":{"id":"n4173","loc":[-85.621331,41.951439]},"n4174":{"id":"n4174","loc":[-85.621031,41.951443]},"n4175":{"id":"n4175","loc":[-85.621836,41.951724]},"n4176":{"id":"n4176","loc":[-85.621834,41.951621]},"n4177":{"id":"n4177","loc":[-85.62197,41.951619]},"n4178":{"id":"n4178","loc":[-85.621972,41.951722]},"n4179":{"id":"n4179","loc":[-85.621772,41.951638]},"n418":{"id":"n418","loc":[-85.633547,41.943896]},"n4180":{"id":"n4180","loc":[-85.621772,41.951715]},"n4181":{"id":"n4181","loc":[-85.621699,41.951716]},"n4182":{"id":"n4182","loc":[-85.6217,41.951722]},"n4183":{"id":"n4183","loc":[-85.621641,41.951722]},"n4184":{"id":"n4184","loc":[-85.62164,41.951639]},"n4185":{"id":"n4185","loc":[-85.621505,41.951655]},"n4186":{"id":"n4186","loc":[-85.621505,41.951729]},"n4187":{"id":"n4187","loc":[-85.621389,41.951729]},"n4188":{"id":"n4188","loc":[-85.62139,41.951654]},"n4189":{"id":"n4189","loc":[-85.621105,41.951635]},"n419":{"id":"n419","loc":[-85.633467,41.944075]},"n4190":{"id":"n4190","loc":[-85.621104,41.951576]},"n4191":{"id":"n4191","loc":[-85.621168,41.951576]},"n4192":{"id":"n4192","loc":[-85.621168,41.951595]},"n4193":{"id":"n4193","loc":[-85.621261,41.951595]},"n4194":{"id":"n4194","loc":[-85.621261,41.951646]},"n4195":{"id":"n4195","loc":[-85.621294,41.951646]},"n4196":{"id":"n4196","loc":[-85.621294,41.951732]},"n4197":{"id":"n4197","loc":[-85.621251,41.951732]},"n4198":{"id":"n4198","loc":[-85.621251,41.95174]},"n4199":{"id":"n4199","loc":[-85.621175,41.951741]},"n42":{"id":"n42","loc":[-85.635996,41.942727]},"n420":{"id":"n420","loc":[-85.633578,41.944055]},"n4200":{"id":"n4200","loc":[-85.621175,41.951651]},"n4201":{"id":"n4201","loc":[-85.621189,41.951651]},"n4202":{"id":"n4202","loc":[-85.621189,41.951635]},"n4203":{"id":"n4203","loc":[-85.620554,41.951641]},"n4204":{"id":"n4204","loc":[-85.620555,41.951742]},"n4205":{"id":"n4205","loc":[-85.620719,41.951742]},"n4206":{"id":"n4206","loc":[-85.620719,41.951731]},"n4207":{"id":"n4207","loc":[-85.620803,41.95173]},"n4208":{"id":"n4208","loc":[-85.620803,41.951603]},"n4209":{"id":"n4209","loc":[-85.62072,41.951603]},"n421":{"id":"n421","loc":[-85.633462,41.944125]},"n4210":{"id":"n4210","loc":[-85.620721,41.951641]},"n4211":{"id":"n4211","loc":[-85.620269,41.953053]},"n4212":{"id":"n4212","loc":[-85.620229,41.953051]},"n4213":{"id":"n4213","loc":[-85.620231,41.953013]},"n4214":{"id":"n4214","loc":[-85.620271,41.953015]},"n4215":{"id":"n4215","loc":[-85.620215,41.953133]},"n4216":{"id":"n4216","loc":[-85.62013,41.953134]},"n4217":{"id":"n4217","loc":[-85.620129,41.953083]},"n4218":{"id":"n4218","loc":[-85.620214,41.953082]},"n4219":{"id":"n4219","loc":[-85.62016,41.953272]},"n422":{"id":"n422","loc":[-85.633372,41.944061]},"n4220":{"id":"n4220","loc":[-85.620046,41.953273]},"n4221":{"id":"n4221","loc":[-85.620045,41.953171]},"n4222":{"id":"n4222","loc":[-85.620088,41.953171]},"n4223":{"id":"n4223","loc":[-85.620087,41.953162]},"n4224":{"id":"n4224","loc":[-85.620121,41.953162]},"n4225":{"id":"n4225","loc":[-85.620121,41.953173]},"n4226":{"id":"n4226","loc":[-85.620157,41.953173]},"n4227":{"id":"n4227","loc":[-85.620158,41.953196]},"n4228":{"id":"n4228","loc":[-85.620189,41.953196]},"n4229":{"id":"n4229","loc":[-85.620189,41.953246]},"n423":{"id":"n423","loc":[-85.633509,41.943981]},"n4230":{"id":"n4230","loc":[-85.62016,41.953246]},"n4231":{"id":"n4231","loc":[-85.6195,41.954012]},"n4232":{"id":"n4232","loc":[-85.619438,41.954057]},"n4233":{"id":"n4233","loc":[-85.619418,41.954043]},"n4234":{"id":"n4234","loc":[-85.619381,41.954069]},"n4235":{"id":"n4235","loc":[-85.619399,41.954083]},"n4236":{"id":"n4236","loc":[-85.619339,41.954126]},"n4237":{"id":"n4237","loc":[-85.619584,41.954313]},"n4238":{"id":"n4238","loc":[-85.619743,41.954198]},"n4239":{"id":"n4239","loc":[-85.619453,41.954727]},"n424":{"id":"n424","loc":[-85.635421,41.945367]},"n4240":{"id":"n4240","loc":[-85.619503,41.954581]},"n4241":{"id":"n4241","loc":[-85.619597,41.954472]},"n4242":{"id":"n4242","loc":[-85.619862,41.95419]},"n4243":{"id":"n4243","loc":[-85.619506,41.953907]},"n4244":{"id":"n4244","loc":[-85.619261,41.9541]},"n4245":{"id":"n4245","loc":[-85.619246,41.954139]},"n4246":{"id":"n4246","loc":[-85.619244,41.9542]},"n4247":{"id":"n4247","loc":[-85.619259,41.954243]},"n4248":{"id":"n4248","loc":[-85.619285,41.954274]},"n4249":{"id":"n4249","loc":[-85.619123,41.954381]},"n425":{"id":"n425","loc":[-85.634425,41.943552]},"n4250":{"id":"n4250","loc":[-85.619641,41.954607]},"n4251":{"id":"n4251","loc":[-85.619383,41.954615]},"n4252":{"id":"n4252","loc":[-85.61896,41.954391]},"n4253":{"id":"n4253","loc":[-85.619211,41.954178]},"n4254":{"id":"n4254","loc":[-85.619115,41.954102]},"n4255":{"id":"n4255","loc":[-85.619519,41.953821]},"n4256":{"id":"n4256","loc":[-85.619956,41.954156]},"n4257":{"id":"n4257","loc":[-85.619851,41.954266]},"n4258":{"id":"n4258","loc":[-85.619779,41.95436]},"n4259":{"id":"n4259","loc":[-85.620525,41.954364]},"n426":{"id":"n426","loc":[-85.634248,41.943654]},"n4260":{"id":"n4260","loc":[-85.620398,41.954365]},"n4261":{"id":"n4261","loc":[-85.620398,41.954324]},"n4262":{"id":"n4262","loc":[-85.620525,41.954323]},"n4263":{"id":"n4263","loc":[-85.620359,41.954588]},"n4264":{"id":"n4264","loc":[-85.620321,41.954588]},"n4265":{"id":"n4265","loc":[-85.620321,41.954599]},"n4266":{"id":"n4266","loc":[-85.620296,41.954599]},"n4267":{"id":"n4267","loc":[-85.620296,41.954587]},"n4268":{"id":"n4268","loc":[-85.620262,41.954588]},"n4269":{"id":"n4269","loc":[-85.620261,41.954516]},"n427":{"id":"n427","loc":[-85.634177,41.943585]},"n4270":{"id":"n4270","loc":[-85.620282,41.954516]},"n4271":{"id":"n4271","loc":[-85.620282,41.954373]},"n4272":{"id":"n4272","loc":[-85.620378,41.954373]},"n4273":{"id":"n4273","loc":[-85.620379,41.954486]},"n4274":{"id":"n4274","loc":[-85.620348,41.954486]},"n4275":{"id":"n4275","loc":[-85.620348,41.954537]},"n4276":{"id":"n4276","loc":[-85.620359,41.954537]},"n4277":{"id":"n4277","loc":[-85.620463,41.95521]},"n4278":{"id":"n4278","loc":[-85.620409,41.955273]},"n4279":{"id":"n4279","loc":[-85.620205,41.955177]},"n428":{"id":"n428","loc":[-85.634354,41.943484]},"n4280":{"id":"n4280","loc":[-85.620288,41.955079]},"n4281":{"id":"n4281","loc":[-85.620379,41.955121]},"n4282":{"id":"n4282","loc":[-85.620349,41.955157]},"n4283":{"id":"n4283","loc":[-85.620083,41.955101]},"n4284":{"id":"n4284","loc":[-85.620083,41.954986]},"n4285":{"id":"n4285","loc":[-85.620016,41.954986]},"n4286":{"id":"n4286","loc":[-85.620016,41.954999]},"n4287":{"id":"n4287","loc":[-85.619941,41.954999]},"n4288":{"id":"n4288","loc":[-85.619941,41.954988]},"n4289":{"id":"n4289","loc":[-85.619815,41.954988]},"n429":{"id":"n429","loc":[-85.638577,41.943212]},"n4290":{"id":"n4290","loc":[-85.619815,41.955075]},"n4291":{"id":"n4291","loc":[-85.619948,41.955075]},"n4292":{"id":"n4292","loc":[-85.619948,41.955082]},"n4293":{"id":"n4293","loc":[-85.620004,41.955082]},"n4294":{"id":"n4294","loc":[-85.620004,41.955101]},"n4295":{"id":"n4295","loc":[-85.619293,41.955127]},"n4296":{"id":"n4296","loc":[-85.619208,41.955124]},"n4297":{"id":"n4297","loc":[-85.619212,41.955061]},"n4298":{"id":"n4298","loc":[-85.619297,41.955064]},"n4299":{"id":"n4299","loc":[-85.619068,41.954936]},"n43":{"id":"n43","loc":[-85.637047,41.943054]},"n430":{"id":"n430","loc":[-85.638576,41.943219]},"n4300":{"id":"n4300","loc":[-85.619003,41.954936]},"n4301":{"id":"n4301","loc":[-85.619004,41.955003]},"n4302":{"id":"n4302","loc":[-85.618994,41.955003]},"n4303":{"id":"n4303","loc":[-85.618994,41.955016]},"n4304":{"id":"n4304","loc":[-85.618973,41.955016]},"n4305":{"id":"n4305","loc":[-85.618973,41.955071]},"n4306":{"id":"n4306","loc":[-85.619061,41.955071]},"n4307":{"id":"n4307","loc":[-85.61906,41.955024]},"n4308":{"id":"n4308","loc":[-85.619105,41.955024]},"n4309":{"id":"n4309","loc":[-85.619105,41.954956]},"n431":{"id":"n431","loc":[-85.638653,41.943078]},"n4310":{"id":"n4310","loc":[-85.619068,41.954956]},"n4311":{"id":"n4311","loc":[-85.618294,41.954596]},"n4312":{"id":"n4312","loc":[-85.618235,41.954602]},"n4313":{"id":"n4313","loc":[-85.618222,41.954535]},"n4314":{"id":"n4314","loc":[-85.618281,41.954529]},"n4315":{"id":"n4315","loc":[-85.618593,41.954556]},"n4316":{"id":"n4316","loc":[-85.618551,41.954565]},"n4317":{"id":"n4317","loc":[-85.618545,41.954552]},"n4318":{"id":"n4318","loc":[-85.618493,41.954563]},"n4319":{"id":"n4319","loc":[-85.618449,41.954455]},"n432":{"id":"n432","loc":[-85.638654,41.943148]},"n4320":{"id":"n4320","loc":[-85.618544,41.954434]},"n4321":{"id":"n4321","loc":[-85.622545,41.950775]},"n4322":{"id":"n4322","loc":[-85.622546,41.950843]},"n4323":{"id":"n4323","loc":[-85.622503,41.950844]},"n4324":{"id":"n4324","loc":[-85.622503,41.950853]},"n4325":{"id":"n4325","loc":[-85.622479,41.950853]},"n4326":{"id":"n4326","loc":[-85.622478,41.950843]},"n4327":{"id":"n4327","loc":[-85.622425,41.950843]},"n4328":{"id":"n4328","loc":[-85.622425,41.950808]},"n4329":{"id":"n4329","loc":[-85.622366,41.950809]},"n433":{"id":"n433","loc":[-85.638387,41.943151]},"n4330":{"id":"n4330","loc":[-85.622364,41.950673]},"n4331":{"id":"n4331","loc":[-85.622448,41.950673]},"n4332":{"id":"n4332","loc":[-85.622449,41.950732]},"n4333":{"id":"n4333","loc":[-85.622479,41.950731]},"n4334":{"id":"n4334","loc":[-85.622479,41.950775]},"n4335":{"id":"n4335","loc":[-85.621909,41.950641]},"n4336":{"id":"n4336","loc":[-85.621864,41.950641]},"n4337":{"id":"n4337","loc":[-85.621865,41.950567]},"n4338":{"id":"n4338","loc":[-85.62191,41.950567]},"n4339":{"id":"n4339","loc":[-85.621787,41.950829]},"n434":{"id":"n434","loc":[-85.638386,41.94308]},"n4340":{"id":"n4340","loc":[-85.621786,41.950775]},"n4341":{"id":"n4341","loc":[-85.621588,41.950776]},"n4342":{"id":"n4342","loc":[-85.621589,41.950848]},"n4343":{"id":"n4343","loc":[-85.621737,41.950847]},"n4344":{"id":"n4344","loc":[-85.621737,41.950829]},"n4345":{"id":"n4345","loc":[-85.621509,41.950846]},"n4346":{"id":"n4346","loc":[-85.621399,41.950846]},"n4347":{"id":"n4347","loc":[-85.621398,41.95073]},"n4348":{"id":"n4348","loc":[-85.621509,41.95073]},"n4349":{"id":"n4349","loc":[-85.621217,41.950841]},"n435":{"id":"n435","loc":[-85.634427,41.943533]},"n4350":{"id":"n4350","loc":[-85.6211,41.95084]},"n4351":{"id":"n4351","loc":[-85.6211,41.950777]},"n4352":{"id":"n4352","loc":[-85.621218,41.950778]},"n4353":{"id":"n4353","loc":[-85.621055,41.950764]},"n4354":{"id":"n4354","loc":[-85.621054,41.950826]},"n4355":{"id":"n4355","loc":[-85.620988,41.950826]},"n4356":{"id":"n4356","loc":[-85.620988,41.950843]},"n4357":{"id":"n4357","loc":[-85.620842,41.950843]},"n4358":{"id":"n4358","loc":[-85.620842,41.950764]},"n4359":{"id":"n4359","loc":[-85.620825,41.950922]},"n436":{"id":"n436","loc":[-85.63428,41.943229]},"n4360":{"id":"n4360","loc":[-85.620824,41.950553]},"n4361":{"id":"n4361","loc":[-85.620543,41.950771]},"n4362":{"id":"n4362","loc":[-85.620431,41.950772]},"n4363":{"id":"n4363","loc":[-85.62043,41.950585]},"n4364":{"id":"n4364","loc":[-85.620542,41.950585]},"n4365":{"id":"n4365","loc":[-85.62068,41.950505]},"n4366":{"id":"n4366","loc":[-85.620681,41.950552]},"n4367":{"id":"n4367","loc":[-85.620589,41.950553]},"n4368":{"id":"n4368","loc":[-85.620588,41.950506]},"n4369":{"id":"n4369","loc":[-85.620539,41.950407]},"n437":{"id":"n437","loc":[-85.634499,41.943461]},"n4370":{"id":"n4370","loc":[-85.62054,41.950504]},"n4371":{"id":"n4371","loc":[-85.620416,41.950504]},"n4372":{"id":"n4372","loc":[-85.620416,41.950408]},"n4373":{"id":"n4373","loc":[-85.620742,41.95038]},"n4374":{"id":"n4374","loc":[-85.620527,41.95038]},"n4375":{"id":"n4375","loc":[-85.620528,41.950408]},"n4376":{"id":"n4376","loc":[-85.622449,41.950373]},"n4377":{"id":"n4377","loc":[-85.622452,41.950397]},"n4378":{"id":"n4378","loc":[-85.622336,41.950404]},"n4379":{"id":"n4379","loc":[-85.622333,41.950379]},"n438":{"id":"n438","loc":[-85.634514,41.943486]},"n4380":{"id":"n4380","loc":[-85.622263,41.950324]},"n4381":{"id":"n4381","loc":[-85.622261,41.950256]},"n4382":{"id":"n4382","loc":[-85.62236,41.950254]},"n4383":{"id":"n4383","loc":[-85.62236,41.95027]},"n4384":{"id":"n4384","loc":[-85.622402,41.950281]},"n4385":{"id":"n4385","loc":[-85.622403,41.9503]},"n4386":{"id":"n4386","loc":[-85.622439,41.950299]},"n4387":{"id":"n4387","loc":[-85.62244,41.950334]},"n4388":{"id":"n4388","loc":[-85.622414,41.950335]},"n4389":{"id":"n4389","loc":[-85.622414,41.95036]},"n439":{"id":"n439","loc":[-85.63452,41.943511]},"n4390":{"id":"n4390","loc":[-85.62231,41.950362]},"n4391":{"id":"n4391","loc":[-85.622309,41.950323]},"n4392":{"id":"n4392","loc":[-85.622015,41.950539]},"n4393":{"id":"n4393","loc":[-85.621909,41.95054]},"n4394":{"id":"n4394","loc":[-85.621909,41.950472]},"n4395":{"id":"n4395","loc":[-85.622015,41.950471]},"n4396":{"id":"n4396","loc":[-85.62199,41.950439]},"n4397":{"id":"n4397","loc":[-85.621956,41.95044]},"n4398":{"id":"n4398","loc":[-85.621955,41.950405]},"n4399":{"id":"n4399","loc":[-85.621988,41.950404]},"n44":{"id":"n44","loc":[-85.636799,41.943055]},"n440":{"id":"n440","loc":[-85.63451,41.943534]},"n4400":{"id":"n4400","loc":[-85.621668,41.950418]},"n4401":{"id":"n4401","loc":[-85.621667,41.950343]},"n4402":{"id":"n4402","loc":[-85.621745,41.950342]},"n4403":{"id":"n4403","loc":[-85.621744,41.950306]},"n4404":{"id":"n4404","loc":[-85.621764,41.950306]},"n4405":{"id":"n4405","loc":[-85.621763,41.950254]},"n4406":{"id":"n4406","loc":[-85.621861,41.950253]},"n4407":{"id":"n4407","loc":[-85.621861,41.950274]},"n4408":{"id":"n4408","loc":[-85.621896,41.950273]},"n4409":{"id":"n4409","loc":[-85.621898,41.950389]},"n441":{"id":"n441","loc":[-85.634483,41.943556]},"n4410":{"id":"n4410","loc":[-85.621843,41.95039]},"n4411":{"id":"n4411","loc":[-85.621843,41.950425]},"n4412":{"id":"n4412","loc":[-85.621789,41.950425]},"n4413":{"id":"n4413","loc":[-85.621789,41.950386]},"n4414":{"id":"n4414","loc":[-85.621752,41.950387]},"n4415":{"id":"n4415","loc":[-85.621753,41.950417]},"n4416":{"id":"n4416","loc":[-85.621556,41.950562]},"n4417":{"id":"n4417","loc":[-85.621552,41.950217]},"n4418":{"id":"n4418","loc":[-85.621788,41.950562]},"n4419":{"id":"n4419","loc":[-85.621155,41.950562]},"n442":{"id":"n442","loc":[-85.63419,41.943713]},"n4420":{"id":"n4420","loc":[-85.622473,41.950551]},"n4421":{"id":"n4421","loc":[-85.622043,41.950551]},"n4422":{"id":"n4422","loc":[-85.62142,41.950454]},"n4423":{"id":"n4423","loc":[-85.621315,41.950455]},"n4424":{"id":"n4424","loc":[-85.621313,41.950311]},"n4425":{"id":"n4425","loc":[-85.621388,41.950311]},"n4426":{"id":"n4426","loc":[-85.621387,41.950261]},"n4427":{"id":"n4427","loc":[-85.621468,41.95026]},"n4428":{"id":"n4428","loc":[-85.621468,41.950271]},"n4429":{"id":"n4429","loc":[-85.621503,41.95027]},"n443":{"id":"n443","loc":[-85.634462,41.943294]},"n4430":{"id":"n4430","loc":[-85.621505,41.950353]},"n4431":{"id":"n4431","loc":[-85.621483,41.950354]},"n4432":{"id":"n4432","loc":[-85.621483,41.950392]},"n4433":{"id":"n4433","loc":[-85.621419,41.950393]},"n4434":{"id":"n4434","loc":[-85.621213,41.95039]},"n4435":{"id":"n4435","loc":[-85.621127,41.950391]},"n4436":{"id":"n4436","loc":[-85.621126,41.950357]},"n4437":{"id":"n4437","loc":[-85.621094,41.950357]},"n4438":{"id":"n4438","loc":[-85.621094,41.950391]},"n4439":{"id":"n4439","loc":[-85.620977,41.950392]},"n444":{"id":"n444","loc":[-85.634298,41.943389]},"n4440":{"id":"n4440","loc":[-85.620975,41.950278]},"n4441":{"id":"n4441","loc":[-85.621087,41.950277]},"n4442":{"id":"n4442","loc":[-85.621088,41.950331]},"n4443":{"id":"n4443","loc":[-85.621211,41.950312]},"n4444":{"id":"n4444","loc":[-85.621104,41.950313]},"n4445":{"id":"n4445","loc":[-85.621105,41.950331]},"n4446":{"id":"n4446","loc":[-85.620706,41.950328]},"n4447":{"id":"n4447","loc":[-85.620606,41.950327]},"n4448":{"id":"n4448","loc":[-85.620607,41.950261]},"n4449":{"id":"n4449","loc":[-85.620707,41.950262]},"n445":{"id":"n445","loc":[-85.634527,41.943623]},"n4450":{"id":"n4450","loc":[-85.620599,41.950336]},"n4451":{"id":"n4451","loc":[-85.620559,41.950336]},"n4452":{"id":"n4452","loc":[-85.620559,41.950299]},"n4453":{"id":"n4453","loc":[-85.620599,41.950299]},"n4454":{"id":"n4454","loc":[-85.620545,41.950357]},"n4455":{"id":"n4455","loc":[-85.620418,41.950357]},"n4456":{"id":"n4456","loc":[-85.620417,41.950257]},"n4457":{"id":"n4457","loc":[-85.620544,41.950256]},"n4458":{"id":"n4458","loc":[-85.620246,41.950131],"tags":{"highway":"crossing"}},"n4459":{"id":"n4459","loc":[-85.620252,41.950956]},"n446":{"id":"n446","loc":[-85.634608,41.943577]},"n4460":{"id":"n4460","loc":[-85.620245,41.950179]},"n4461":{"id":"n4461","loc":[-85.620246,41.950088]},"n4462":{"id":"n4462","loc":[-85.620251,41.950885]},"n4463":{"id":"n4463","loc":[-85.620103,41.950884],"tags":{"crossing":"zebra","highway":"crossing"}},"n4464":{"id":"n4464","loc":[-85.619992,41.950884]},"n4465":{"id":"n4465","loc":[-85.619704,41.951008]},"n4466":{"id":"n4466","loc":[-85.619599,41.951122]},"n4467":{"id":"n4467","loc":[-85.619264,41.951486]},"n4468":{"id":"n4468","loc":[-85.619179,41.951573],"tags":{"highway":"crossing"}},"n4469":{"id":"n4469","loc":[-85.620251,41.950999],"tags":{"highway":"crossing"}},"n447":{"id":"n447","loc":[-85.634555,41.943531]},"n4470":{"id":"n4470","loc":[-85.620249,41.951066]},"n4471":{"id":"n4471","loc":[-85.620256,41.951374]},"n4472":{"id":"n4472","loc":[-85.620249,41.951389]},"n4473":{"id":"n4473","loc":[-85.620249,41.951407]},"n4474":{"id":"n4474","loc":[-85.620255,41.951423]},"n4475":{"id":"n4475","loc":[-85.62026,41.951853]},"n4476":{"id":"n4476","loc":[-85.620262,41.951894],"tags":{"highway":"crossing"}},"n4477":{"id":"n4477","loc":[-85.620265,41.951957]},"n4478":{"id":"n4478","loc":[-85.620262,41.952135]},"n4479":{"id":"n4479","loc":[-85.620241,41.952424]},"n448":{"id":"n448","loc":[-85.634555,41.943482]},"n4480":{"id":"n4480","loc":[-85.620213,41.952583]},"n4481":{"id":"n4481","loc":[-85.620158,41.952754]},"n4482":{"id":"n4482","loc":[-85.620065,41.952942]},"n4483":{"id":"n4483","loc":[-85.619753,41.953439]},"n4484":{"id":"n4484","loc":[-85.619605,41.953626]},"n4485":{"id":"n4485","loc":[-85.619381,41.953834]},"n4486":{"id":"n4486","loc":[-85.619069,41.954066]},"n4487":{"id":"n4487","loc":[-85.618674,41.95429]},"n4488":{"id":"n4488","loc":[-85.621816,41.952389]},"n4489":{"id":"n4489","loc":[-85.6217,41.952386]},"n449":{"id":"n449","loc":[-85.634509,41.943427]},"n4490":{"id":"n4490","loc":[-85.621705,41.952306]},"n4491":{"id":"n4491","loc":[-85.621821,41.95231]},"n4492":{"id":"n4492","loc":[-85.621819,41.952272]},"n4493":{"id":"n4493","loc":[-85.621778,41.952272]},"n4494":{"id":"n4494","loc":[-85.621778,41.952199]},"n4495":{"id":"n4495","loc":[-85.621818,41.952199]},"n4496":{"id":"n4496","loc":[-85.621754,41.952281]},"n4497":{"id":"n4497","loc":[-85.621701,41.95228]},"n4498":{"id":"n4498","loc":[-85.621702,41.952197]},"n4499":{"id":"n4499","loc":[-85.621755,41.952197]},"n45":{"id":"n45","loc":[-85.636791,41.942792]},"n450":{"id":"n450","loc":[-85.63453,41.943365]},"n4500":{"id":"n4500","loc":[-85.628201,41.954694],"tags":{"highway":"stop","stop":"all"}},"n4501":{"id":"n4501","loc":[-85.627921,41.954783],"tags":{"highway":"stop","stop":"all"}},"n4502":{"id":"n4502","loc":[-85.62775,41.954696],"tags":{"highway":"stop","stop":"all"}},"n4503":{"id":"n4503","loc":[-85.628046,41.954591],"tags":{"highway":"stop","stop":"all"}},"n4504":{"id":"n4504","loc":[-85.631074,41.957428],"tags":{"highway":"stop"}},"n4505":{"id":"n4505","loc":[-85.630768,41.957429],"tags":{"highway":"stop"}},"n4506":{"id":"n4506","loc":[-85.629888,41.957432],"tags":{"highway":"stop"}},"n4507":{"id":"n4507","loc":[-85.629565,41.957433],"tags":{"highway":"stop"}},"n4508":{"id":"n4508","loc":[-85.629559,41.957343]},"n4509":{"id":"n4509","loc":[-85.628723,41.95735]},"n451":{"id":"n451","loc":[-85.634356,41.943468]},"n4510":{"id":"n4510","loc":[-85.62842,41.957515]},"n4511":{"id":"n4511","loc":[-85.627561,41.957525]},"n4512":{"id":"n4512","loc":[-85.630323,41.957508]},"n4513":{"id":"n4513","loc":[-85.630811,41.957506]},"n4514":{"id":"n4514","loc":[-85.630839,41.960874]},"n4515":{"id":"n4515","loc":[-85.631035,41.957506]},"n4516":{"id":"n4516","loc":[-85.632027,41.9575]},"n4517":{"id":"n4517","loc":[-85.631038,41.958066]},"n4518":{"id":"n4518","loc":[-85.630787,41.954769]},"n4519":{"id":"n4519","loc":[-85.630806,41.957342]},"n452":{"id":"n452","loc":[-85.634123,41.943596]},"n4520":{"id":"n4520","loc":[-85.630809,41.957428],"tags":{"highway":"crossing"}},"n4521":{"id":"n4521","loc":[-85.630912,41.957506],"tags":{"highway":"crossing"}},"n4522":{"id":"n4522","loc":[-85.631033,41.957428],"tags":{"highway":"crossing"}},"n4523":{"id":"n4523","loc":[-85.631032,41.957341]},"n4524":{"id":"n4524","loc":[-85.63091,41.957341],"tags":{"highway":"crossing"}},"n4525":{"id":"n4525","loc":[-85.631027,41.95597]},"n4526":{"id":"n4526","loc":[-85.631027,41.955913],"tags":{"highway":"crossing"}},"n4527":{"id":"n4527","loc":[-85.631025,41.955873]},"n4528":{"id":"n4528","loc":[-85.631073,41.955913],"tags":{"highway":"stop"}},"n4529":{"id":"n4529","loc":[-85.631007,41.954766]},"n453":{"id":"n453","loc":[-85.634709,41.943926]},"n4530":{"id":"n4530","loc":[-85.630881,41.954768],"tags":{"highway":"crossing"}},"n4531":{"id":"n4531","loc":[-85.628022,41.954776]},"n4532":{"id":"n4532","loc":[-85.627385,41.95584]},"n4533":{"id":"n4533","loc":[-85.627329,41.955937]},"n4534":{"id":"n4534","loc":[-85.626583,41.957153]},"n4535":{"id":"n4535","loc":[-85.629675,41.954564],"tags":{"highway":"stop"}},"n4536":{"id":"n4536","loc":[-85.630881,41.954806],"tags":{"highway":"stop"}},"n4537":{"id":"n4537","loc":[-85.630879,41.954564],"tags":{"highway":"stop"}},"n4538":{"id":"n4538","loc":[-85.630784,41.954682],"tags":{"highway":"crossing"}},"n4539":{"id":"n4539","loc":[-85.63078,41.954595]},"n454":{"id":"n454","loc":[-85.63525,41.943855]},"n4540":{"id":"n4540","loc":[-85.630879,41.954595],"tags":{"highway":"crossing"}},"n4541":{"id":"n4541","loc":[-85.631004,41.954594]},"n4542":{"id":"n4542","loc":[-85.631006,41.954681],"tags":{"highway":"crossing"}},"n4543":{"id":"n4543","loc":[-85.631045,41.959036],"tags":{"highway":"stop"}},"n4544":{"id":"n4544","loc":[-85.632071,41.959029],"tags":{"highway":"stop"}},"n4545":{"id":"n4545","loc":[-85.632257,41.959027],"tags":{"highway":"stop"}},"n4546":{"id":"n4546","loc":[-85.631966,41.957427],"tags":{"highway":"stop"}},"n4547":{"id":"n4547","loc":[-85.632297,41.957426],"tags":{"highway":"stop"}},"n4548":{"id":"n4548","loc":[-85.631976,41.955911],"tags":{"highway":"give_way"}},"n4549":{"id":"n4549","loc":[-85.632272,41.955911],"tags":{"highway":"give_way"}},"n455":{"id":"n455","loc":[-85.635224,41.943869]},"n4550":{"id":"n4550","loc":[-85.632097,41.954805],"tags":{"highway":"stop"}},"n4551":{"id":"n4551","loc":[-85.632094,41.954566],"tags":{"highway":"stop"}},"n4552":{"id":"n4552","loc":[-85.626519,41.957256]},"n4553":{"id":"n4553","loc":[-85.625334,41.959165]},"n4554":{"id":"n4554","loc":[-85.626483,41.95806]},"n4555":{"id":"n4555","loc":[-85.626481,41.958175]},"n4556":{"id":"n4556","loc":[-85.626412,41.958174]},"n4557":{"id":"n4557","loc":[-85.626412,41.958202]},"n4558":{"id":"n4558","loc":[-85.62628,41.958201]},"n4559":{"id":"n4559","loc":[-85.626283,41.958057]},"n456":{"id":"n456","loc":[-85.638854,41.943104]},"n4560":{"id":"n4560","loc":[-85.622763,41.95109],"tags":{"highway":"stop"}},"n4561":{"id":"n4561","loc":[-85.622858,41.950876],"tags":{"emergency":"fire_hydrant"}},"n4562":{"id":"n4562","loc":[-85.624073,41.950393]},"n4563":{"id":"n4563","loc":[-85.624077,41.950924]},"n4564":{"id":"n4564","loc":[-85.624599,41.950984],"tags":{"highway":"stop"}},"n4565":{"id":"n4565","loc":[-85.624831,41.95119],"tags":{"emergency":"fire_hydrant"}},"n4566":{"id":"n4566","loc":[-85.624437,41.952568],"tags":{"emergency":"fire_hydrant"}},"n4567":{"id":"n4567","loc":[-85.624077,41.954606],"tags":{"emergency":"fire_hydrant"}},"n4568":{"id":"n4568","loc":[-85.624263,41.954888]},"n4569":{"id":"n4569","loc":[-85.624206,41.954919]},"n457":{"id":"n457","loc":[-85.635186,41.943901]},"n4570":{"id":"n4570","loc":[-85.624154,41.954865]},"n4571":{"id":"n4571","loc":[-85.624212,41.954835]},"n4572":{"id":"n4572","loc":[-85.622442,41.954401],"tags":{"emergency":"fire_hydrant"}},"n4573":{"id":"n4573","loc":[-85.619751,41.954658],"tags":{"emergency":"fire_hydrant"}},"n4574":{"id":"n4574","loc":[-85.617785,41.954534]},"n4575":{"id":"n4575","loc":[-85.617416,41.954721]},"n4576":{"id":"n4576","loc":[-85.617662,41.95474]},"n4577":{"id":"n4577","loc":[-85.618014,41.954717]},"n4578":{"id":"n4578","loc":[-85.617886,41.954671]},"n4579":{"id":"n4579","loc":[-85.617831,41.954612]},"n458":{"id":"n458","loc":[-85.635162,41.943917]},"n4580":{"id":"n4580","loc":[-85.617968,41.954752]},"n4581":{"id":"n4581","loc":[-85.617815,41.954752]},"n4582":{"id":"n4582","loc":[-85.617938,41.954695]},"n4583":{"id":"n4583","loc":[-85.617856,41.954642],"tags":{"highway":"stop"}},"n4584":{"id":"n4584","loc":[-85.619116,41.954164],"tags":{"man_made":"flagpole"}},"n4585":{"id":"n4585","loc":[-85.619569,41.953255],"tags":{"emergency":"fire_hydrant"}},"n4586":{"id":"n4586","loc":[-85.620352,41.951894],"tags":{"highway":"stop"}},"n4587":{"id":"n4587","loc":[-85.620485,41.951948],"tags":{"emergency":"fire_hydrant"}},"n4588":{"id":"n4588","loc":[-85.620316,41.950999],"tags":{"highway":"stop"}},"n4589":{"id":"n4589","loc":[-85.620311,41.950131],"tags":{"highway":"stop"}},"n459":{"id":"n459","loc":[-85.634856,41.943905]},"n4590":{"id":"n4590","loc":[-85.620374,41.95018],"tags":{"emergency":"fire_hydrant"}},"n4591":{"id":"n4591","loc":[-85.620301,41.949239],"tags":{"highway":"stop"}},"n4592":{"id":"n4592","loc":[-85.620278,41.947443],"tags":{"highway":"stop"}},"n4593":{"id":"n4593","loc":[-85.619844,41.947444],"tags":{"highway":"stop"}},"n4594":{"id":"n4594","loc":[-85.620191,41.947352],"tags":{"emergency":"fire_hydrant"}},"n4595":{"id":"n4595","loc":[-85.622819,41.947493],"tags":{"emergency":"fire_hydrant"}},"n4596":{"id":"n4596","loc":[-85.622744,41.947541],"tags":{"highway":"stop"}},"n4597":{"id":"n4597","loc":[-85.622739,41.947316],"tags":{"highway":"stop"}},"n4598":{"id":"n4598","loc":[-85.622909,41.948333],"tags":{"highway":"give_way"}},"n4599":{"id":"n4599","loc":[-85.622593,41.948333],"tags":{"highway":"give_way"}},"n46":{"id":"n46","loc":[-85.637131,41.94307]},"n460":{"id":"n460","loc":[-85.634811,41.944007]},"n4600":{"id":"n4600","loc":[-85.622835,41.948387],"tags":{"emergency":"fire_hydrant"}},"n4601":{"id":"n4601","loc":[-85.622768,41.949125],"tags":{"highway":"stop"}},"n4602":{"id":"n4602","loc":[-85.622769,41.949325],"tags":{"highway":"stop"}},"n4603":{"id":"n4603","loc":[-85.622837,41.949329],"tags":{"emergency":"fire_hydrant"}},"n4604":{"id":"n4604","loc":[-85.622614,41.950113],"tags":{"highway":"give_way"}},"n4605":{"id":"n4605","loc":[-85.624777,41.949219],"tags":{"highway":"stop"}},"n4606":{"id":"n4606","loc":[-85.624849,41.949106],"tags":{"emergency":"fire_hydrant"}},"n4607":{"id":"n4607","loc":[-85.624858,41.950119],"tags":{"emergency":"fire_hydrant"}},"n4608":{"id":"n4608","loc":[-85.624752,41.948334],"tags":{"highway":"give_way"}},"n4609":{"id":"n4609","loc":[-85.624845,41.948422],"tags":{"emergency":"fire_hydrant"}},"n461":{"id":"n461","loc":[-85.634987,41.943112]},"n4610":{"id":"n4610","loc":[-85.62484,41.947539],"tags":{"emergency":"fire_hydrant"}},"n4611":{"id":"n4611","loc":[-85.62476,41.947428],"tags":{"highway":"stop"}},"n4612":{"id":"n4612","loc":[-85.620286,41.950926]},"n4613":{"id":"n4613","loc":[-85.618237,41.950963]},"n4614":{"id":"n4614","loc":[-85.618107,41.950876]},"n4615":{"id":"n4615","loc":[-85.618131,41.950393]},"n4616":{"id":"n4616","loc":[-85.61823,41.9499]},"n4617":{"id":"n4617","loc":[-85.619138,41.950212]},"n4618":{"id":"n4618","loc":[-85.619299,41.950388]},"n4619":{"id":"n4619","loc":[-85.619306,41.950897]},"n462":{"id":"n462","loc":[-85.634698,41.943194]},"n4620":{"id":"n4620","loc":[-85.619155,41.950958]},"n4621":{"id":"n4621","loc":[-85.620079,41.947715]},"n4622":{"id":"n4622","loc":[-85.619674,41.947728]},"n4623":{"id":"n4623","loc":[-85.619634,41.947735]},"n4624":{"id":"n4624","loc":[-85.619587,41.947756],"tags":{"barrier":"gate"}},"n4625":{"id":"n4625","loc":[-85.61953,41.947796]},"n4626":{"id":"n4626","loc":[-85.619475,41.947847]},"n4627":{"id":"n4627","loc":[-85.619433,41.947903]},"n4628":{"id":"n4628","loc":[-85.619402,41.947982]},"n4629":{"id":"n4629","loc":[-85.619394,41.948043]},"n463":{"id":"n463","loc":[-85.634632,41.943219]},"n4630":{"id":"n4630","loc":[-85.619395,41.948476]},"n4631":{"id":"n4631","loc":[-85.618367,41.947452]},"n4632":{"id":"n4632","loc":[-85.618371,41.947567],"tags":{"barrier":"gate"}},"n4633":{"id":"n4633","loc":[-85.618341,41.947622]},"n4634":{"id":"n4634","loc":[-85.618138,41.94773]},"n4635":{"id":"n4635","loc":[-85.618078,41.947814]},"n4636":{"id":"n4636","loc":[-85.618072,41.948009]},"n4637":{"id":"n4637","loc":[-85.618269,41.947666]},"n4638":{"id":"n4638","loc":[-85.618099,41.947765]},"n4639":{"id":"n4639","loc":[-85.618378,41.954453]},"n464":{"id":"n464","loc":[-85.63459,41.943239]},"n4640":{"id":"n4640","loc":[-85.618198,41.95453]},"n4641":{"id":"n4641","loc":[-85.618212,41.954623]},"n4642":{"id":"n4642","loc":[-85.635211,41.943103],"tags":{"leisure":"picnic_table"}},"n4643":{"id":"n4643","loc":[-85.635345,41.943448],"tags":{"leisure":"picnic_table"}},"n4644":{"id":"n4644","loc":[-85.635901,41.943353],"tags":{"amenity":"bench"}},"n4645":{"id":"n4645","loc":[-85.635815,41.942638],"tags":{"highway":"stop"}},"n4646":{"id":"n4646","loc":[-85.635355,41.942044],"tags":{"leisure":"picnic_table"}},"n4647":{"id":"n4647","loc":[-85.635206,41.942045],"tags":{"leisure":"picnic_table"}},"n4648":{"id":"n4648","loc":[-85.63504,41.941992],"tags":{"leisure":"picnic_table"}},"n4649":{"id":"n4649","loc":[-85.635185,41.942001]},"n465":{"id":"n465","loc":[-85.634555,41.943263]},"n4650":{"id":"n4650","loc":[-85.635176,41.942021]},"n4651":{"id":"n4651","loc":[-85.635127,41.942008]},"n4652":{"id":"n4652","loc":[-85.635136,41.941988]},"n4653":{"id":"n4653","loc":[-85.635,41.941709],"tags":{"emergency":"fire_hydrant"}},"n4654":{"id":"n4654","loc":[-85.634893,41.941801]},"n4655":{"id":"n4655","loc":[-85.634937,41.941843]},"n4656":{"id":"n4656","loc":[-85.634963,41.941859]},"n4657":{"id":"n4657","loc":[-85.635027,41.941904]},"n4658":{"id":"n4658","loc":[-85.63494,41.94187]},"n4659":{"id":"n4659","loc":[-85.634951,41.941871]},"n466":{"id":"n466","loc":[-85.634526,41.943289]},"n4660":{"id":"n4660","loc":[-85.634753,41.941701],"tags":{"amenity":"drinking_water"}},"n4661":{"id":"n4661","loc":[-85.634717,41.941804],"tags":{"amenity":"bench"}},"n4662":{"id":"n4662","loc":[-85.634554,41.941883],"tags":{"amenity":"bench"}},"n4663":{"id":"n4663","loc":[-85.635002,41.941579],"tags":{"amenity":"fountain"}},"n4664":{"id":"n4664","loc":[-85.635258,41.94188],"tags":{"amenity":"waste_basket"}},"n4665":{"id":"n4665","loc":[-85.635262,41.941581],"tags":{"amenity":"bench"}},"n4666":{"id":"n4666","loc":[-85.635319,41.941744],"tags":{"amenity":"bench"}},"n4667":{"id":"n4667","loc":[-85.634702,41.941473],"tags":{"amenity":"waste_basket"}},"n4668":{"id":"n4668","loc":[-85.633981,41.941966],"tags":{"amenity":"bench"}},"n4669":{"id":"n4669","loc":[-85.63388,41.941743]},"n467":{"id":"n467","loc":[-85.635163,41.944985]},"n4670":{"id":"n4670","loc":[-85.633746,41.941741]},"n4671":{"id":"n4671","loc":[-85.633749,41.941664]},"n4672":{"id":"n4672","loc":[-85.633883,41.941667]},"n4673":{"id":"n4673","loc":[-85.634283,41.941183],"tags":{"leisure":"picnic_table"}},"n4674":{"id":"n4674","loc":[-85.634046,41.941102],"tags":{"amenity":"bbq"}},"n4675":{"id":"n4675","loc":[-85.63401,41.941093],"tags":{"amenity":"bbq"}},"n4676":{"id":"n4676","loc":[-85.633408,41.940862],"tags":{"amenity":"bench"}},"n4677":{"id":"n4677","loc":[-85.633359,41.940651],"tags":{"amenity":"bench"}},"n4678":{"id":"n4678","loc":[-85.634109,41.940831]},"n4679":{"id":"n4679","loc":[-85.63396,41.940867]},"n468":{"id":"n468","loc":[-85.635095,41.945035]},"n4680":{"id":"n4680","loc":[-85.633816,41.940913]},"n4681":{"id":"n4681","loc":[-85.633237,41.940455]},"n4682":{"id":"n4682","loc":[-85.634453,41.940025],"tags":{"emergency":"fire_hydrant"}},"n4683":{"id":"n4683","loc":[-85.635692,41.940218],"tags":{"emergency":"fire_hydrant"}},"n4684":{"id":"n4684","loc":[-85.635566,41.940102],"tags":{"highway":"stop"}},"n4685":{"id":"n4685","loc":[-85.635961,41.940125],"tags":{"highway":"stop"}},"n4686":{"id":"n4686","loc":[-85.635883,41.94012],"tags":{"crossing":"zebra","highway":"crossing"}},"n4687":{"id":"n4687","loc":[-85.635883,41.94006]},"n4688":{"id":"n4688","loc":[-85.635768,41.940051],"tags":{"crossing":"zebra","highway":"crossing"}},"n4689":{"id":"n4689","loc":[-85.635669,41.940043]},"n469":{"id":"n469","loc":[-85.634269,41.944431]},"n4690":{"id":"n4690","loc":[-85.635661,41.940107],"tags":{"crossing":"zebra","highway":"crossing"}},"n4691":{"id":"n4691","loc":[-85.635424,41.941005],"tags":{"amenity":"fountain"}},"n4692":{"id":"n4692","loc":[-85.635542,41.941371],"tags":{"amenity":"bench"}},"n4693":{"id":"n4693","loc":[-85.635709,41.941341],"tags":{"emergency":"fire_hydrant"}},"n4694":{"id":"n4694","loc":[-85.637038,41.942513],"tags":{"highway":"stop"}},"n4695":{"id":"n4695","loc":[-85.637174,41.941354],"tags":{"highway":"stop"}},"n4696":{"id":"n4696","loc":[-85.637091,41.941273],"tags":{"emergency":"fire_hydrant"}},"n4697":{"id":"n4697","loc":[-85.638058,41.941346],"tags":{"highway":"give_way"}},"n4698":{"id":"n4698","loc":[-85.638359,41.941344],"tags":{"highway":"give_way"}},"n4699":{"id":"n4699","loc":[-85.638288,41.941236],"tags":{"emergency":"fire_hydrant"}},"n47":{"id":"n47","loc":[-85.636693,41.943073]},"n470":{"id":"n470","loc":[-85.634352,41.944376]},"n4700":{"id":"n4700","loc":[-85.63935,41.94128],"tags":{"emergency":"fire_hydrant"}},"n4701":{"id":"n4701","loc":[-85.639277,41.941337],"tags":{"highway":"give_way"}},"n4702":{"id":"n4702","loc":[-85.639548,41.941334],"tags":{"highway":"give_way"}},"n4703":{"id":"n4703","loc":[-85.642191,41.940039]},"n4704":{"id":"n4704","loc":[-85.640585,41.941263],"tags":{"emergency":"fire_hydrant"}},"n4705":{"id":"n4705","loc":[-85.64049,41.941327],"tags":{"highway":"stop"}},"n4706":{"id":"n4706","loc":[-85.640803,41.941324],"tags":{"highway":"stop"}},"n4707":{"id":"n4707","loc":[-85.641717,41.941317],"tags":{"highway":"stop"}},"n4708":{"id":"n4708","loc":[-85.641846,41.941415],"tags":{"highway":"stop"}},"n4709":{"id":"n4709","loc":[-85.641756,41.941392],"tags":{"emergency":"fire_hydrant"}},"n471":{"id":"n471","loc":[-85.634747,41.944561],"tags":{"railway":"crossing"}},"n4710":{"id":"n4710","loc":[-85.642014,41.941313],"tags":{"highway":"stop"}},"n4711":{"id":"n4711","loc":[-85.641854,41.942455],"tags":{"highway":"stop"}},"n4712":{"id":"n4712","loc":[-85.641859,41.942739],"tags":{"highway":"stop"}},"n4713":{"id":"n4713","loc":[-85.640754,41.942707],"tags":{"emergency":"fire_hydrant"}},"n4714":{"id":"n4714","loc":[-85.640669,41.942716],"tags":{"highway":"stop"}},"n4715":{"id":"n4715","loc":[-85.640664,41.942478],"tags":{"highway":"stop"}},"n4716":{"id":"n4716","loc":[-85.63964,41.94274],"tags":{"man_made":"flagpole"}},"n4717":{"id":"n4717","loc":[-85.639455,41.942731],"tags":{"highway":"stop"}},"n4718":{"id":"n4718","loc":[-85.63945,41.942492],"tags":{"highway":"stop"}},"n4719":{"id":"n4719","loc":[-85.639527,41.942505],"tags":{"emergency":"fire_hydrant"}},"n472":{"id":"n472","loc":[-85.634667,41.944613]},"n4720":{"id":"n4720","loc":[-85.638238,41.942745],"tags":{"highway":"stop"}},"n4721":{"id":"n4721","loc":[-85.638233,41.942511],"tags":{"highway":"stop"}},"n4722":{"id":"n4722","loc":[-85.638018,41.94299],"tags":{"amenity":"waste_disposal"}},"n4723":{"id":"n4723","loc":[-85.637918,41.944152],"tags":{"amenity":"waste_basket"}},"n4724":{"id":"n4724","loc":[-85.635902,41.943291],"tags":{"leisure":"picnic_table"}},"n4725":{"id":"n4725","loc":[-85.63704,41.942741],"tags":{"highway":"stop"}},"n4726":{"id":"n4726","loc":[-85.633467,41.943818],"tags":{"highway":"stop"}},"n4727":{"id":"n4727","loc":[-85.633987,41.943531],"tags":{"highway":"stop"}},"n4728":{"id":"n4728","loc":[-85.632154,41.943539],"tags":{"emergency":"fire_hydrant"}},"n4729":{"id":"n4729","loc":[-85.633567,41.944641],"tags":{"amenity":"bench"}},"n473":{"id":"n473","loc":[-85.634161,41.944371]},"n4730":{"id":"n4730","loc":[-85.633127,41.944574],"tags":{"amenity":"bench"}},"n4731":{"id":"n4731","loc":[-85.633439,41.944871],"tags":{"amenity":"bench"}},"n4732":{"id":"n4732","loc":[-85.633676,41.944799],"tags":{"amenity":"waste_basket"}},"n4733":{"id":"n4733","loc":[-85.633466,41.944862],"tags":{"amenity":"waste_basket"}},"n4734":{"id":"n4734","loc":[-85.633451,41.944847],"tags":{"emergency":"fire_hydrant"}},"n4735":{"id":"n4735","loc":[-85.634202,41.945543],"tags":{"amenity":"waste_basket"}},"n4736":{"id":"n4736","loc":[-85.634652,41.945472],"tags":{"leisure":"picnic_table"}},"n4737":{"id":"n4737","loc":[-85.6347,41.945445],"tags":{"leisure":"picnic_table"}},"n4738":{"id":"n4738","loc":[-85.634646,41.945662],"tags":{"emergency":"fire_hydrant"}},"n4739":{"id":"n4739","loc":[-85.634673,41.945687],"tags":{"amenity":"waste_basket"}},"n474":{"id":"n474","loc":[-85.633861,41.944117]},"n4740":{"id":"n4740","loc":[-85.63449,41.945827],"tags":{"amenity":"clock","display":"analog"}},"n4741":{"id":"n4741","loc":[-85.63481,41.946056],"tags":{"highway":"stop"}},"n4742":{"id":"n4742","loc":[-85.634814,41.946176],"tags":{"amenity":"post_box"}},"n4743":{"id":"n4743","loc":[-85.638744,41.945328]},"n4744":{"id":"n4744","loc":[-85.63867,41.945228],"tags":{"amenity":"bench"}},"n4745":{"id":"n4745","loc":[-85.639487,41.945042],"tags":{"highway":"stop"}},"n4746":{"id":"n4746","loc":[-85.639635,41.94387],"tags":{"highway":"stop"}},"n4747":{"id":"n4747","loc":[-85.639549,41.943756],"tags":{"emergency":"fire_hydrant"}},"n4748":{"id":"n4748","loc":[-85.64055,41.943862],"tags":{"highway":"stop"}},"n4749":{"id":"n4749","loc":[-85.640864,41.943859],"tags":{"highway":"stop"}},"n475":{"id":"n475","loc":[-85.633906,41.943535]},"n4750":{"id":"n4750","loc":[-85.640718,41.945022],"tags":{"highway":"stop"}},"n4751":{"id":"n4751","loc":[-85.640664,41.945076],"tags":{"emergency":"fire_hydrant"}},"n4752":{"id":"n4752","loc":[-85.641913,41.94502],"tags":{"highway":"stop"}},"n4753":{"id":"n4753","loc":[-85.641838,41.945076],"tags":{"emergency":"fire_hydrant"}},"n4754":{"id":"n4754","loc":[-85.642045,41.94385],"tags":{"highway":"give_way"}},"n4755":{"id":"n4755","loc":[-85.641738,41.943852],"tags":{"highway":"give_way"}},"n4756":{"id":"n4756","loc":[-85.642928,41.943843],"tags":{"highway":"stop"}},"n4757":{"id":"n4757","loc":[-85.64305,41.943902],"tags":{"emergency":"fire_hydrant"}},"n4758":{"id":"n4758","loc":[-85.642986,41.945105],"tags":{"highway":"stop"}},"n4759":{"id":"n4759","loc":[-85.643136,41.94502],"tags":{"highway":"stop"}},"n476":{"id":"n476","loc":[-85.63423,41.943692]},"n4760":{"id":"n4760","loc":[-85.63169,41.947812]},"n4761":{"id":"n4761","loc":[-85.631307,41.947655]},"n4762":{"id":"n4762","loc":[-85.631407,41.947413]},"n4763":{"id":"n4763","loc":[-85.631173,41.947306]},"n4764":{"id":"n4764","loc":[-85.631316,41.947145]},"n4765":{"id":"n4765","loc":[-85.631476,41.947087]},"n4766":{"id":"n4766","loc":[-85.631793,41.946871]},"n4767":{"id":"n4767","loc":[-85.631884,41.946723]},"n4768":{"id":"n4768","loc":[-85.631814,41.946397]},"n4769":{"id":"n4769","loc":[-85.631382,41.947685]},"n477":{"id":"n477","loc":[-85.635096,41.942814]},"n4770":{"id":"n4770","loc":[-85.63109,41.947819]},"n4771":{"id":"n4771","loc":[-85.630921,41.947961]},"n4772":{"id":"n4772","loc":[-85.630249,41.947709]},"n4773":{"id":"n4773","loc":[-85.630149,41.947451]},"n4774":{"id":"n4774","loc":[-85.629733,41.947339]},"n4775":{"id":"n4775","loc":[-85.629755,41.946948]},"n4776":{"id":"n4776","loc":[-85.630457,41.947103]},"n4777":{"id":"n4777","loc":[-85.630934,41.946939]},"n4778":{"id":"n4778","loc":[-85.631277,41.946852]},"n4779":{"id":"n4779","loc":[-85.63142,41.946781]},"n478":{"id":"n478","loc":[-85.635058,41.942795]},"n4780":{"id":"n4780","loc":[-85.631116,41.946474]},"n4781":{"id":"n4781","loc":[-85.63073,41.945965]},"n4782":{"id":"n4782","loc":[-85.631337,41.94571]},"n4783":{"id":"n4783","loc":[-85.631589,41.945487]},"n4784":{"id":"n4784","loc":[-85.632278,41.945784]},"n4785":{"id":"n4785","loc":[-85.632105,41.946034]},"n4786":{"id":"n4786","loc":[-85.632532,41.946198]},"n4787":{"id":"n4787","loc":[-85.632566,41.946151]},"n4788":{"id":"n4788","loc":[-85.632684,41.946196]},"n4789":{"id":"n4789","loc":[-85.628676,41.947106]},"n479":{"id":"n479","loc":[-85.635002,41.94279]},"n4790":{"id":"n4790","loc":[-85.628973,41.946476]},"n4791":{"id":"n4791","loc":[-85.629094,41.946079]},"n4792":{"id":"n4792","loc":[-85.629226,41.94578]},"n4793":{"id":"n4793","loc":[-85.629479,41.945682]},"n4794":{"id":"n4794","loc":[-85.630606,41.94569]},"n4795":{"id":"n4795","loc":[-85.631255,41.945588]},"n4796":{"id":"n4796","loc":[-85.631546,41.945281]},"n4797":{"id":"n4797","loc":[-85.631629,41.944823]},"n4798":{"id":"n4798","loc":[-85.631766,41.944958]},"n4799":{"id":"n4799","loc":[-85.631689,41.945318]},"n48":{"id":"n48","loc":[-85.636689,41.94276]},"n480":{"id":"n480","loc":[-85.634908,41.94279]},"n4800":{"id":"n4800","loc":[-85.615069,41.945527]},"n4801":{"id":"n4801","loc":[-85.615058,41.946677]},"n4802":{"id":"n4802","loc":[-85.613692,41.946689]},"n4803":{"id":"n4803","loc":[-85.613475,41.946531]},"n4804":{"id":"n4804","loc":[-85.611717,41.946252]},"n4805":{"id":"n4805","loc":[-85.611353,41.946385]},"n4806":{"id":"n4806","loc":[-85.611304,41.947397]},"n4807":{"id":"n4807","loc":[-85.610564,41.947401]},"n4808":{"id":"n4808","loc":[-85.610553,41.947122]},"n4809":{"id":"n4809","loc":[-85.610194,41.946992]},"n481":{"id":"n481","loc":[-85.634478,41.942342]},"n4810":{"id":"n4810","loc":[-85.609976,41.946628]},"n4811":{"id":"n4811","loc":[-85.609769,41.946523]},"n4812":{"id":"n4812","loc":[-85.609307,41.946523]},"n4813":{"id":"n4813","loc":[-85.609035,41.946462]},"n4814":{"id":"n4814","loc":[-85.609018,41.943277]},"n4815":{"id":"n4815","loc":[-85.609617,41.943423]},"n4816":{"id":"n4816","loc":[-85.610471,41.943447]},"n4817":{"id":"n4817","loc":[-85.621491,41.949168]},"n4818":{"id":"n4818","loc":[-85.620266,41.94917]},"n4819":{"id":"n4819","loc":[-85.620262,41.947557]},"n482":{"id":"n482","loc":[-85.634521,41.942254]},"n4820":{"id":"n4820","loc":[-85.620825,41.947556]},"n4821":{"id":"n4821","loc":[-85.620827,41.948371]},"n4822":{"id":"n4822","loc":[-85.621489,41.94837]},"n4823":{"id":"n4823","loc":[-85.622865,41.950928]},"n4824":{"id":"n4824","loc":[-85.622858,41.949744]},"n4825":{"id":"n4825","loc":[-85.623696,41.949714]},"n4826":{"id":"n4826","loc":[-85.623696,41.949647]},"n4827":{"id":"n4827","loc":[-85.624019,41.949647]},"n4828":{"id":"n4828","loc":[-85.624024,41.950093]},"n4829":{"id":"n4829","loc":[-85.622885,41.949711]},"n483":{"id":"n483","loc":[-85.63425,41.941819]},"n4830":{"id":"n4830","loc":[-85.624584,41.951049]},"n4831":{"id":"n4831","loc":[-85.624669,41.9511]},"n4832":{"id":"n4832","loc":[-85.624316,41.952218]},"n4833":{"id":"n4833","loc":[-85.623819,41.952094]},"n4834":{"id":"n4834","loc":[-85.623385,41.952101]},"n4835":{"id":"n4835","loc":[-85.623456,41.951238]},"n4836":{"id":"n4836","loc":[-85.623535,41.951051]},"n4837":{"id":"n4837","loc":[-85.624693,41.950921]},"n4838":{"id":"n4838","loc":[-85.624727,41.950897]},"n4839":{"id":"n4839","loc":[-85.624869,41.950341]},"n484":{"id":"n484","loc":[-85.634324,41.942131]},"n4840":{"id":"n4840","loc":[-85.624859,41.949284]},"n4841":{"id":"n4841","loc":[-85.624788,41.949262]},"n4842":{"id":"n4842","loc":[-85.62402,41.949265]},"n4843":{"id":"n4843","loc":[-85.610382,41.954663]},"n4844":{"id":"n4844","loc":[-85.605675,41.954667]},"n4845":{"id":"n4845","loc":[-85.605669,41.949407]},"n4846":{"id":"n4846","loc":[-85.610376,41.949404]},"n4847":{"id":"n4847","loc":[-85.605552,41.958536]},"n4848":{"id":"n4848","loc":[-85.595755,41.958588]},"n4849":{"id":"n4849","loc":[-85.595732,41.956419]},"n485":{"id":"n485","loc":[-85.634211,41.941374]},"n4850":{"id":"n4850","loc":[-85.596908,41.955605]},"n4851":{"id":"n4851","loc":[-85.597723,41.955596]},"n4852":{"id":"n4852","loc":[-85.597715,41.954967]},"n4853":{"id":"n4853","loc":[-85.5874,41.955018]},"n4854":{"id":"n4854","loc":[-85.586615,41.955124]},"n4855":{"id":"n4855","loc":[-85.58613,41.955293]},"n4856":{"id":"n4856","loc":[-85.586166,41.962122]},"n4857":{"id":"n4857","loc":[-85.587008,41.955052]},"n4858":{"id":"n4858","loc":[-85.591685,41.95499]},"n4859":{"id":"n4859","loc":[-85.591718,41.956649]},"n486":{"id":"n486","loc":[-85.634085,41.940704]},"n4860":{"id":"n4860","loc":[-85.591133,41.956649]},"n4861":{"id":"n4861","loc":[-85.591061,41.95582]},"n4862":{"id":"n4862","loc":[-85.590677,41.95613]},"n4863":{"id":"n4863","loc":[-85.590826,41.956369]},"n4864":{"id":"n4864","loc":[-85.591016,41.954991]},"n4865":{"id":"n4865","loc":[-85.587656,41.954855]},"n4866":{"id":"n4866","loc":[-85.5964,41.955274]},"n4867":{"id":"n4867","loc":[-85.58776,41.96178]},"n4868":{"id":"n4868","loc":[-85.601172,41.960448]},"n4869":{"id":"n4869","loc":[-85.589489,41.960478]},"n487":{"id":"n487","loc":[-85.635567,41.940944]},"n4870":{"id":"n4870","loc":[-85.586664,41.960493]},"n4871":{"id":"n4871","loc":[-85.591227,41.95676]},"n4872":{"id":"n4872","loc":[-85.589424,41.958093]},"n4873":{"id":"n4873","loc":[-85.588779,41.957611]},"n4874":{"id":"n4874","loc":[-85.590583,41.956278]},"n4875":{"id":"n4875","loc":[-85.590759,41.957106]},"n4876":{"id":"n4876","loc":[-85.592213,41.958218]},"n4877":{"id":"n4877","loc":[-85.592262,41.958279]},"n4878":{"id":"n4878","loc":[-85.592304,41.958358]},"n4879":{"id":"n4879","loc":[-85.592351,41.95849]},"n488":{"id":"n488","loc":[-85.635542,41.940919]},"n4880":{"id":"n4880","loc":[-85.592363,41.958605]},"n4881":{"id":"n4881","loc":[-85.592383,41.96047]},"n4882":{"id":"n4882","loc":[-85.592376,41.959808]},"n4883":{"id":"n4883","loc":[-85.600825,41.959779]},"n4884":{"id":"n4884","loc":[-85.601084,41.959844]},"n4885":{"id":"n4885","loc":[-85.601144,41.959908]},"n4886":{"id":"n4886","loc":[-85.601164,41.960008]},"n4887":{"id":"n4887","loc":[-85.601162,41.960125]},"n4888":{"id":"n4888","loc":[-85.601134,41.960221]},"n4889":{"id":"n4889","loc":[-85.600993,41.960353]},"n489":{"id":"n489","loc":[-85.635514,41.940906]},"n4890":{"id":"n4890","loc":[-85.600794,41.960449]},"n4891":{"id":"n4891","loc":[-85.60098,41.959792]},"n4892":{"id":"n4892","loc":[-85.601067,41.960294]},"n4893":{"id":"n4893","loc":[-85.596829,41.959793]},"n4894":{"id":"n4894","loc":[-85.596839,41.960459]},"n4895":{"id":"n4895","loc":[-85.589364,41.958048]},"n4896":{"id":"n4896","loc":[-85.587374,41.959511]},"n4897":{"id":"n4897","loc":[-85.587286,41.959564]},"n4898":{"id":"n4898","loc":[-85.587163,41.959632]},"n4899":{"id":"n4899","loc":[-85.586694,41.959865]},"n49":{"id":"n49","loc":[-85.637127,41.942757]},"n490":{"id":"n490","loc":[-85.635469,41.940896]},"n4900":{"id":"n4900","loc":[-85.586634,41.959921]},"n4901":{"id":"n4901","loc":[-85.586607,41.960001]},"n4902":{"id":"n4902","loc":[-85.586599,41.960099]},"n4903":{"id":"n4903","loc":[-85.586602,41.96034]},"n4904":{"id":"n4904","loc":[-85.586669,41.960439]},"n4905":{"id":"n4905","loc":[-85.586758,41.960493]},"n4906":{"id":"n4906","loc":[-85.586618,41.960391]},"n4907":{"id":"n4907","loc":[-85.591201,41.956352]},"n4908":{"id":"n4908","loc":[-85.59112,41.954843]},"n4909":{"id":"n4909","loc":[-85.591536,41.956349]},"n491":{"id":"n491","loc":[-85.635667,41.940826]},"n4910":{"id":"n4910","loc":[-85.590953,41.956354]},"n4911":{"id":"n4911","loc":[-85.591468,41.956406]},"n4912":{"id":"n4912","loc":[-85.591469,41.956478]},"n4913":{"id":"n4913","loc":[-85.591123,41.956481]},"n4914":{"id":"n4914","loc":[-85.591121,41.956409]},"n4915":{"id":"n4915","loc":[-85.590826,41.955954]},"n4916":{"id":"n4916","loc":[-85.590612,41.956115]},"n4917":{"id":"n4917","loc":[-85.590402,41.955962]},"n4918":{"id":"n4918","loc":[-85.590622,41.955804]},"n4919":{"id":"n4919","loc":[-85.59011,41.956502]},"n492":{"id":"n492","loc":[-85.636197,41.940599]},"n4920":{"id":"n4920","loc":[-85.589877,41.956668]},"n4921":{"id":"n4921","loc":[-85.589777,41.95659]},"n4922":{"id":"n4922","loc":[-85.59001,41.956424]},"n4923":{"id":"n4923","loc":[-85.589595,41.956427]},"n4924":{"id":"n4924","loc":[-85.589434,41.956549]},"n4925":{"id":"n4925","loc":[-85.589262,41.956424]},"n4926":{"id":"n4926","loc":[-85.589422,41.956302]},"n4927":{"id":"n4927","loc":[-85.589358,41.956286]},"n4928":{"id":"n4928","loc":[-85.5892,41.956408]},"n4929":{"id":"n4929","loc":[-85.589032,41.956288]},"n493":{"id":"n493","loc":[-85.6362,41.940686]},"n4930":{"id":"n4930","loc":[-85.58919,41.956166]},"n4931":{"id":"n4931","loc":[-85.589165,41.956132]},"n4932":{"id":"n4932","loc":[-85.589002,41.956253]},"n4933":{"id":"n4933","loc":[-85.588826,41.956122]},"n4934":{"id":"n4934","loc":[-85.588989,41.956001]},"n4935":{"id":"n4935","loc":[-85.588673,41.955757]},"n4936":{"id":"n4936","loc":[-85.588502,41.955882]},"n4937":{"id":"n4937","loc":[-85.588339,41.955759]},"n4938":{"id":"n4938","loc":[-85.58851,41.955633]},"n4939":{"id":"n4939","loc":[-85.590382,41.955892]},"n494":{"id":"n494","loc":[-85.635969,41.94069]},"n4940":{"id":"n4940","loc":[-85.589923,41.956231]},"n4941":{"id":"n4941","loc":[-85.58984,41.956168]},"n4942":{"id":"n4942","loc":[-85.5903,41.95583]},"n4943":{"id":"n4943","loc":[-85.589636,41.956038]},"n4944":{"id":"n4944","loc":[-85.589546,41.956105]},"n4945":{"id":"n4945","loc":[-85.589045,41.955729]},"n4946":{"id":"n4946","loc":[-85.589135,41.955662]},"n4947":{"id":"n4947","loc":[-85.590718,41.955293]},"n4948":{"id":"n4948","loc":[-85.590718,41.955374]},"n4949":{"id":"n4949","loc":[-85.589211,41.955369]},"n495":{"id":"n495","loc":[-85.635965,41.940561]},"n4950":{"id":"n4950","loc":[-85.589212,41.955287]},"n4951":{"id":"n4951","loc":[-85.589675,41.956817]},"n4952":{"id":"n4952","loc":[-85.58947,41.95697]},"n4953":{"id":"n4953","loc":[-85.589219,41.956784]},"n4954":{"id":"n4954","loc":[-85.589425,41.95663]},"n4955":{"id":"n4955","loc":[-85.589373,41.95702]},"n4956":{"id":"n4956","loc":[-85.589171,41.957172]},"n4957":{"id":"n4957","loc":[-85.588962,41.957019]},"n4958":{"id":"n4958","loc":[-85.589164,41.956867]},"n4959":{"id":"n4959","loc":[-85.588881,41.955006]},"n496":{"id":"n496","loc":[-85.636031,41.94056]},"n4960":{"id":"n4960","loc":[-85.588804,41.955006]},"n4961":{"id":"n4961","loc":[-85.604773,41.954521]},"n4962":{"id":"n4962","loc":[-85.601603,41.954527]},"n4963":{"id":"n4963","loc":[-85.600823,41.954169]},"n4964":{"id":"n4964","loc":[-85.600828,41.950191]},"n4965":{"id":"n4965","loc":[-85.601673,41.949457]},"n4966":{"id":"n4966","loc":[-85.604464,41.949488]},"n4967":{"id":"n4967","loc":[-85.60538,41.950212]},"n4968":{"id":"n4968","loc":[-85.605395,41.954108]},"n4969":{"id":"n4969","loc":[-85.604771,41.954109]},"n497":{"id":"n497","loc":[-85.636032,41.940602]},"n4970":{"id":"n4970","loc":[-85.600613,41.953916]},"n4971":{"id":"n4971","loc":[-85.599758,41.954649]},"n4972":{"id":"n4972","loc":[-85.591194,41.954663]},"n4973":{"id":"n4973","loc":[-85.591182,41.950465]},"n4974":{"id":"n4974","loc":[-85.591871,41.950464]},"n4975":{"id":"n4975","loc":[-85.591868,41.949209]},"n4976":{"id":"n4976","loc":[-85.592155,41.949209]},"n4977":{"id":"n4977","loc":[-85.592155,41.94848]},"n4978":{"id":"n4978","loc":[-85.600615,41.948482]},"n4979":{"id":"n4979","loc":[-85.605421,41.949378]},"n498":{"id":"n498","loc":[-85.635776,41.940583]},"n4980":{"id":"n4980","loc":[-85.600614,41.949373]},"n4981":{"id":"n4981","loc":[-85.601316,41.94849]},"n4982":{"id":"n4982","loc":[-85.601592,41.947641]},"n4983":{"id":"n4983","loc":[-85.60395,41.947618]},"n4984":{"id":"n4984","loc":[-85.603973,41.948114]},"n4985":{"id":"n4985","loc":[-85.605398,41.948103]},"n4986":{"id":"n4986","loc":[-85.614017,41.965566]},"n4987":{"id":"n4987","loc":[-85.605787,41.965619]},"n4988":{"id":"n4988","loc":[-85.60577,41.963821]},"n4989":{"id":"n4989","loc":[-85.612886,41.963808]},"n499":{"id":"n499","loc":[-85.63589,41.940578]},"n4990":{"id":"n4990","loc":[-85.613207,41.963705]},"n4991":{"id":"n4991","loc":[-85.613511,41.963525]},"n4992":{"id":"n4992","loc":[-85.613667,41.963305]},"n4993":{"id":"n4993","loc":[-85.613779,41.962983]},"n4994":{"id":"n4994","loc":[-85.613797,41.959709]},"n4995":{"id":"n4995","loc":[-85.613663,41.95936]},"n4996":{"id":"n4996","loc":[-85.61339,41.959064]},"n4997":{"id":"n4997","loc":[-85.610503,41.956898]},"n4998":{"id":"n4998","loc":[-85.610485,41.956595]},"n4999":{"id":"n4999","loc":[-85.613892,41.956621]},"n5":{"id":"n5","loc":[-85.622744,41.95268]},"n50":{"id":"n50","loc":[-85.636673,41.943143]},"n500":{"id":"n500","loc":[-85.636198,41.940578]},"n5000":{"id":"n5000","loc":[-85.613866,41.958574]},"n5001":{"id":"n5001","loc":[-85.615262,41.958561]},"n5002":{"id":"n5002","loc":[-85.615279,41.959541]},"n5003":{"id":"n5003","loc":[-85.615314,41.95597]},"n5004":{"id":"n5004","loc":[-85.613887,41.955988]},"n5005":{"id":"n5005","loc":[-85.613074,41.962244]},"n5006":{"id":"n5006","loc":[-85.611678,41.963354]},"n5007":{"id":"n5007","loc":[-85.611678,41.963487]},"n5008":{"id":"n5008","loc":[-85.606906,41.963502]},"n5009":{"id":"n5009","loc":[-85.605777,41.962657]},"n501":{"id":"n501","loc":[-85.636251,41.940584]},"n5010":{"id":"n5010","loc":[-85.605711,41.9599]},"n5011":{"id":"n5011","loc":[-85.608139,41.9585]},"n5012":{"id":"n5012","loc":[-85.60814,41.956306]},"n5013":{"id":"n5013","loc":[-85.608854,41.95581]},"n5014":{"id":"n5014","loc":[-85.610039,41.955883]},"n5015":{"id":"n5015","loc":[-85.610068,41.956754]},"n5016":{"id":"n5016","loc":[-85.613058,41.959411]},"n5017":{"id":"n5017","loc":[-85.610234,41.957068]},"n5018":{"id":"n5018","loc":[-85.609826,41.95581]},"n5019":{"id":"n5019","loc":[-85.606987,41.958505]},"n502":{"id":"n502","loc":[-85.636279,41.940605]},"n5020":{"id":"n5020","loc":[-85.606498,41.958846]},"n5021":{"id":"n5021","loc":[-85.606013,41.959342]},"n5022":{"id":"n5022","loc":[-85.614553,41.961581]},"n5023":{"id":"n5023","loc":[-85.61465,41.96214]},"n5024":{"id":"n5024","loc":[-85.615277,41.962442]},"n5025":{"id":"n5025","loc":[-85.615451,41.962972]},"n5026":{"id":"n5026","loc":[-85.614355,41.964826]},"n5027":{"id":"n5027","loc":[-85.615133,41.964589]},"n5028":{"id":"n5028","loc":[-85.615342,41.963818]},"n5029":{"id":"n5029","loc":[-85.615971,41.963792]},"n503":{"id":"n503","loc":[-85.636285,41.940633]},"n5030":{"id":"n5030","loc":[-85.615751,41.963122]},"n5031":{"id":"n5031","loc":[-85.616575,41.963123]},"n5032":{"id":"n5032","loc":[-85.612527,41.963846]},"n5033":{"id":"n5033","loc":[-85.630653,41.940709]},"n5034":{"id":"n5034","loc":[-85.629858,41.939568]},"n5035":{"id":"n5035","loc":[-85.629847,41.937926]},"n504":{"id":"n504","loc":[-85.636281,41.940662]},"n505":{"id":"n505","loc":[-85.636266,41.940688]},"n506":{"id":"n506","loc":[-85.636236,41.940701]},"n507":{"id":"n507","loc":[-85.63619,41.940706]},"n508":{"id":"n508","loc":[-85.635892,41.940707]},"n509":{"id":"n509","loc":[-85.635777,41.9407]},"n51":{"id":"n51","loc":[-85.636673,41.942864]},"n510":{"id":"n510","loc":[-85.636044,41.940578]},"n511":{"id":"n511","loc":[-85.635946,41.940578]},"n512":{"id":"n512","loc":[-85.636475,41.940732]},"n513":{"id":"n513","loc":[-85.636475,41.940777]},"n514":{"id":"n514","loc":[-85.636405,41.940777]},"n515":{"id":"n515","loc":[-85.636405,41.940732]},"n516":{"id":"n516","loc":[-85.636471,41.940916]},"n517":{"id":"n517","loc":[-85.636471,41.940961]},"n518":{"id":"n518","loc":[-85.636404,41.940961]},"n519":{"id":"n519","loc":[-85.636404,41.940916]},"n52":{"id":"n52","loc":[-85.636227,41.942864]},"n520":{"id":"n520","loc":[-85.636286,41.941127]},"n521":{"id":"n521","loc":[-85.636203,41.941126]},"n522":{"id":"n522","loc":[-85.636204,41.941083]},"n523":{"id":"n523","loc":[-85.636287,41.941083]},"n524":{"id":"n524","loc":[-85.636124,41.941064]},"n525":{"id":"n525","loc":[-85.636,41.941065]},"n526":{"id":"n526","loc":[-85.636,41.940964]},"n527":{"id":"n527","loc":[-85.636045,41.940964]},"n528":{"id":"n528","loc":[-85.636045,41.940928]},"n529":{"id":"n529","loc":[-85.636111,41.940928]},"n53":{"id":"n53","loc":[-85.636227,41.943143]},"n530":{"id":"n530","loc":[-85.636111,41.940961]},"n531":{"id":"n531","loc":[-85.636123,41.940961]},"n532":{"id":"n532","loc":[-85.636124,41.940997]},"n533":{"id":"n533","loc":[-85.636164,41.940997]},"n534":{"id":"n534","loc":[-85.636164,41.941044]},"n535":{"id":"n535","loc":[-85.636124,41.941044]},"n536":{"id":"n536","loc":[-85.636534,41.941256]},"n537":{"id":"n537","loc":[-85.63645,41.941246]},"n538":{"id":"n538","loc":[-85.636462,41.941189]},"n539":{"id":"n539","loc":[-85.636546,41.941199]},"n54":{"id":"n54","loc":[-85.636198,41.943119]},"n540":{"id":"n540","loc":[-85.636802,41.941226]},"n541":{"id":"n541","loc":[-85.636701,41.941215]},"n542":{"id":"n542","loc":[-85.636709,41.941174]},"n543":{"id":"n543","loc":[-85.636656,41.941168]},"n544":{"id":"n544","loc":[-85.636666,41.941122]},"n545":{"id":"n545","loc":[-85.636781,41.941136]},"n546":{"id":"n546","loc":[-85.636774,41.94117]},"n547":{"id":"n547","loc":[-85.636812,41.941175]},"n548":{"id":"n548","loc":[-85.636803,41.941047]},"n549":{"id":"n549","loc":[-85.636785,41.941047]},"n55":{"id":"n55","loc":[-85.635945,41.94312]},"n550":{"id":"n550","loc":[-85.636785,41.941058]},"n551":{"id":"n551","loc":[-85.636644,41.941059]},"n552":{"id":"n552","loc":[-85.636644,41.941038]},"n553":{"id":"n553","loc":[-85.636581,41.941039]},"n554":{"id":"n554","loc":[-85.636581,41.940995]},"n555":{"id":"n555","loc":[-85.636746,41.940995]},"n556":{"id":"n556","loc":[-85.636746,41.940978]},"n557":{"id":"n557","loc":[-85.636803,41.940978]},"n558":{"id":"n558","loc":[-85.636781,41.940768]},"n559":{"id":"n559","loc":[-85.636783,41.940828]},"n56":{"id":"n56","loc":[-85.635943,41.942909]},"n560":{"id":"n560","loc":[-85.636761,41.940828]},"n561":{"id":"n561","loc":[-85.636762,41.940857]},"n562":{"id":"n562","loc":[-85.636641,41.940859]},"n563":{"id":"n563","loc":[-85.63664,41.940805]},"n564":{"id":"n564","loc":[-85.636676,41.940804]},"n565":{"id":"n565","loc":[-85.636675,41.940769]},"n566":{"id":"n566","loc":[-85.636733,41.94033]},"n567":{"id":"n567","loc":[-85.636471,41.940334]},"n568":{"id":"n568","loc":[-85.636469,41.940262]},"n569":{"id":"n569","loc":[-85.636731,41.940257]},"n57":{"id":"n57","loc":[-85.636227,41.942909]},"n570":{"id":"n570","loc":[-85.636798,41.940419]},"n571":{"id":"n571","loc":[-85.6368,41.940524]},"n572":{"id":"n572","loc":[-85.63664,41.940526]},"n573":{"id":"n573","loc":[-85.636638,41.940421]},"n574":{"id":"n574","loc":[-85.636372,41.940551]},"n575":{"id":"n575","loc":[-85.636338,41.94055]},"n576":{"id":"n576","loc":[-85.636339,41.940524]},"n577":{"id":"n577","loc":[-85.636373,41.940525]},"n578":{"id":"n578","loc":[-85.636388,41.940435]},"n579":{"id":"n579","loc":[-85.636222,41.940436]},"n58":{"id":"n58","loc":[-85.63627,41.943175]},"n580":{"id":"n580","loc":[-85.636222,41.940366]},"n581":{"id":"n581","loc":[-85.636387,41.940365]},"n582":{"id":"n582","loc":[-85.636158,41.940482]},"n583":{"id":"n583","loc":[-85.635963,41.940484]},"n584":{"id":"n584","loc":[-85.635961,41.940399]},"n585":{"id":"n585","loc":[-85.636156,41.940397]},"n586":{"id":"n586","loc":[-85.635987,41.940314]},"n587":{"id":"n587","loc":[-85.635987,41.940268]},"n588":{"id":"n588","loc":[-85.635968,41.940268]},"n589":{"id":"n589","loc":[-85.635967,41.940212]},"n59":{"id":"n59","loc":[-85.635531,41.943176]},"n590":{"id":"n590","loc":[-85.636082,41.940211]},"n591":{"id":"n591","loc":[-85.636083,41.94027]},"n592":{"id":"n592","loc":[-85.636064,41.94027]},"n593":{"id":"n593","loc":[-85.636064,41.940313]},"n594":{"id":"n594","loc":[-85.638071,41.941562]},"n595":{"id":"n595","loc":[-85.637953,41.941562]},"n596":{"id":"n596","loc":[-85.637952,41.941522]},"n597":{"id":"n597","loc":[-85.637876,41.941523]},"n598":{"id":"n598","loc":[-85.637876,41.941471]},"n599":{"id":"n599","loc":[-85.638035,41.94147]},"n6":{"id":"n6","loc":[-85.624925,41.950604]},"n60":{"id":"n60","loc":[-85.63542,41.942883]},"n600":{"id":"n600","loc":[-85.638035,41.941513]},"n601":{"id":"n601","loc":[-85.638071,41.941512]},"n602":{"id":"n602","loc":[-85.637038,41.942543],"tags":{"crossing":"zebra","highway":"crossing"}},"n603":{"id":"n603","loc":[-85.637134,41.942542]},"n604":{"id":"n604","loc":[-85.638122,41.942532]},"n605":{"id":"n605","loc":[-85.638121,41.942478]},"n606":{"id":"n606","loc":[-85.638104,41.941424]},"n607":{"id":"n607","loc":[-85.637115,41.941438]},"n608":{"id":"n608","loc":[-85.637133,41.942453]},"n609":{"id":"n609","loc":[-85.637429,41.942004]},"n61":{"id":"n61","loc":[-85.635701,41.942802]},"n610":{"id":"n610","loc":[-85.637125,41.942004]},"n611":{"id":"n611","loc":[-85.637022,41.942004]},"n612":{"id":"n612","loc":[-85.635952,41.943579]},"n613":{"id":"n613","loc":[-85.635872,41.943594]},"n614":{"id":"n614","loc":[-85.635857,41.943551]},"n615":{"id":"n615","loc":[-85.635937,41.943535]},"n616":{"id":"n616","loc":[-85.63671,41.94344]},"n617":{"id":"n617","loc":[-85.636427,41.94334]},"n618":{"id":"n618","loc":[-85.635353,41.943279]},"n619":{"id":"n619","loc":[-85.635319,41.943257]},"n62":{"id":"n62","loc":[-85.6358,41.942997]},"n620":{"id":"n620","loc":[-85.638786,41.943105]},"n621":{"id":"n621","loc":[-85.634957,41.943146]},"n622":{"id":"n622","loc":[-85.635012,41.943119]},"n623":{"id":"n623","loc":[-85.632409,41.944222]},"n624":{"id":"n624","loc":[-85.631863,41.944749]},"n625":{"id":"n625","loc":[-85.631915,41.944722]},"n626":{"id":"n626","loc":[-85.631884,41.94464]},"n627":{"id":"n627","loc":[-85.631792,41.944359]},"n628":{"id":"n628","loc":[-85.631817,41.944703]},"n629":{"id":"n629","loc":[-85.633464,41.945787]},"n63":{"id":"n63","loc":[-85.635808,41.943176]},"n630":{"id":"n630","loc":[-85.633583,41.945919]},"n631":{"id":"n631","loc":[-85.63382,41.945698]},"n632":{"id":"n632","loc":[-85.633681,41.945571]},"n633":{"id":"n633","loc":[-85.634217,41.946824]},"n634":{"id":"n634","loc":[-85.634271,41.946836]},"n635":{"id":"n635","loc":[-85.634319,41.94573]},"n636":{"id":"n636","loc":[-85.634377,41.945672]},"n637":{"id":"n637","loc":[-85.634909,41.945354]},"n638":{"id":"n638","loc":[-85.634726,41.945493],"tags":{"artwork_type":"mural","tourism":"artwork"}},"n639":{"id":"n639","loc":[-85.63546,41.945612]},"n64":{"id":"n64","loc":[-85.63631,41.943253]},"n640":{"id":"n640","loc":[-85.635561,41.945493]},"n641":{"id":"n641","loc":[-85.635417,41.945565]},"n642":{"id":"n642","loc":[-85.635315,41.945583]},"n643":{"id":"n643","loc":[-85.63506,41.945383]},"n644":{"id":"n644","loc":[-85.635198,41.945199]},"n645":{"id":"n645","loc":[-85.635361,41.94558]},"n646":{"id":"n646","loc":[-85.635017,41.945066]},"n647":{"id":"n647","loc":[-85.634779,41.945206]},"n648":{"id":"n648","loc":[-85.63425,41.945655]},"n649":{"id":"n649","loc":[-85.634247,41.945631]},"n65":{"id":"n65","loc":[-85.635398,41.943259]},"n650":{"id":"n650","loc":[-85.634889,41.945921]},"n651":{"id":"n651","loc":[-85.634889,41.945939]},"n652":{"id":"n652","loc":[-85.634889,41.945761]},"n653":{"id":"n653","loc":[-85.634889,41.945778]},"n654":{"id":"n654","loc":[-85.635112,41.945715]},"n655":{"id":"n655","loc":[-85.635025,41.945714]},"n656":{"id":"n656","loc":[-85.635027,41.945761]},"n657":{"id":"n657","loc":[-85.635438,41.945665]},"n658":{"id":"n658","loc":[-85.635416,41.945676]},"n659":{"id":"n659","loc":[-85.635401,41.945709]},"n66":{"id":"n66","loc":[-85.635336,41.943036]},"n660":{"id":"n660","loc":[-85.635271,41.945566]},"n661":{"id":"n661","loc":[-85.636106,41.946268]},"n662":{"id":"n662","loc":[-85.635867,41.946747]},"n663":{"id":"n663","loc":[-85.636476,41.946797]},"n664":{"id":"n664","loc":[-85.63651,41.946796]},"n665":{"id":"n665","loc":[-85.635367,41.946389]},"n666":{"id":"n666","loc":[-85.635367,41.946437]},"n667":{"id":"n667","loc":[-85.634787,41.946441]},"n668":{"id":"n668","loc":[-85.6358,41.946243]},"n669":{"id":"n669","loc":[-85.635784,41.94622]},"n67":{"id":"n67","loc":[-85.635911,41.942899]},"n670":{"id":"n670","loc":[-85.635727,41.946195]},"n671":{"id":"n671","loc":[-85.635708,41.946588]},"n672":{"id":"n672","loc":[-85.635648,41.946561]},"n673":{"id":"n673","loc":[-85.635624,41.946555]},"n674":{"id":"n674","loc":[-85.635417,41.946559]},"n675":{"id":"n675","loc":[-85.634866,41.946561]},"n676":{"id":"n676","loc":[-85.634866,41.946543]},"n677":{"id":"n677","loc":[-85.635085,41.946546]},"n678":{"id":"n678","loc":[-85.635085,41.946554]},"n679":{"id":"n679","loc":[-85.634584,41.94488]},"n68":{"id":"n68","loc":[-85.635915,41.943156]},"n680":{"id":"n680","loc":[-85.634557,41.944882]},"n681":{"id":"n681","loc":[-85.634455,41.944943]},"n682":{"id":"n682","loc":[-85.634305,41.944968]},"n683":{"id":"n683","loc":[-85.634261,41.944927]},"n684":{"id":"n684","loc":[-85.634132,41.944741]},"n685":{"id":"n685","loc":[-85.633705,41.944759]},"n686":{"id":"n686","loc":[-85.633918,41.944616]},"n687":{"id":"n687","loc":[-85.633974,41.944663]},"n688":{"id":"n688","loc":[-85.6336,41.944665]},"n689":{"id":"n689","loc":[-85.633817,41.944528]},"n69":{"id":"n69","loc":[-85.63631,41.943157]},"n690":{"id":"n690","loc":[-85.633889,41.944485]},"n691":{"id":"n691","loc":[-85.633931,41.944525]},"n692":{"id":"n692","loc":[-85.633864,41.944563]},"n693":{"id":"n693","loc":[-85.633456,41.944524]},"n694":{"id":"n694","loc":[-85.633676,41.944399]},"n695":{"id":"n695","loc":[-85.633352,41.944415]},"n696":{"id":"n696","loc":[-85.633655,41.944234]},"n697":{"id":"n697","loc":[-85.633761,41.94435]},"n698":{"id":"n698","loc":[-85.633254,41.944318]},"n699":{"id":"n699","loc":[-85.633472,41.944188]},"n7":{"id":"n7","loc":[-85.638791,41.943231]},"n70":{"id":"n70","loc":[-85.63579,41.942967]},"n700":{"id":"n700","loc":[-85.633524,41.944237]},"n701":{"id":"n701","loc":[-85.633583,41.944202]},"n702":{"id":"n702","loc":[-85.633632,41.944247]},"n703":{"id":"n703","loc":[-85.633165,41.944228]},"n704":{"id":"n704","loc":[-85.633388,41.944105]},"n705":{"id":"n705","loc":[-85.633117,41.944175]},"n706":{"id":"n706","loc":[-85.633302,41.944077]},"n707":{"id":"n707","loc":[-85.633352,41.944126]},"n708":{"id":"n708","loc":[-85.633052,41.944107]},"n709":{"id":"n709","loc":[-85.633237,41.944009]},"n71":{"id":"n71","loc":[-85.637506,41.942824]},"n710":{"id":"n710","loc":[-85.633187,41.943955]},"n711":{"id":"n711","loc":[-85.633,41.944054]},"n712":{"id":"n712","loc":[-85.633155,41.944265]},"n713":{"id":"n713","loc":[-85.633669,41.944765]},"n714":{"id":"n714","loc":[-85.634468,41.945503]},"n715":{"id":"n715","loc":[-85.63455,41.945566]},"n716":{"id":"n716","loc":[-85.634737,41.945729]},"n717":{"id":"n717","loc":[-85.634753,41.945752]},"n718":{"id":"n718","loc":[-85.634756,41.945781]},"n719":{"id":"n719","loc":[-85.634758,41.945978]},"n72":{"id":"n72","loc":[-85.637511,41.943056]},"n720":{"id":"n720","loc":[-85.634363,41.945548],"tags":{"crossing":"zebra","highway":"crossing"}},"n721":{"id":"n721","loc":[-85.634245,41.945599]},"n722":{"id":"n722","loc":[-85.633474,41.944889]},"n723":{"id":"n723","loc":[-85.632997,41.944418]},"n724":{"id":"n724","loc":[-85.63278,41.944183]},"n725":{"id":"n725","loc":[-85.63331,41.944429]},"n726":{"id":"n726","loc":[-85.633568,41.944829],"tags":{"crossing":"zebra","highway":"crossing"}},"n727":{"id":"n727","loc":[-85.634669,41.94567]},"n728":{"id":"n728","loc":[-85.634462,41.945787]},"n729":{"id":"n729","loc":[-85.634272,41.945625]},"n73":{"id":"n73","loc":[-85.637361,41.943058]},"n730":{"id":"n730","loc":[-85.634344,41.945699],"tags":{"crossing":"zebra","highway":"crossing"}},"n731":{"id":"n731","loc":[-85.634426,41.945783]},"n732":{"id":"n732","loc":[-85.632425,41.944137]},"n733":{"id":"n733","loc":[-85.632302,41.944192]},"n734":{"id":"n734","loc":[-85.632762,41.944174]},"n735":{"id":"n735","loc":[-85.632713,41.944179]},"n736":{"id":"n736","loc":[-85.632411,41.944327]},"n737":{"id":"n737","loc":[-85.632362,41.944341]},"n738":{"id":"n738","loc":[-85.632236,41.944204]},"n739":{"id":"n739","loc":[-85.634939,41.942165]},"n74":{"id":"n74","loc":[-85.637356,41.942825]},"n740":{"id":"n740","loc":[-85.635079,41.941535]},"n741":{"id":"n741","loc":[-85.635112,41.941595]},"n742":{"id":"n742","loc":[-85.635113,41.941633]},"n743":{"id":"n743","loc":[-85.635067,41.941652]},"n744":{"id":"n744","loc":[-85.634989,41.941651]},"n745":{"id":"n745","loc":[-85.634921,41.941609]},"n746":{"id":"n746","loc":[-85.634881,41.941544]},"n747":{"id":"n747","loc":[-85.635537,41.940939]},"n748":{"id":"n748","loc":[-85.635573,41.941048]},"n749":{"id":"n749","loc":[-85.635453,41.94091]},"n75":{"id":"n75","loc":[-85.638097,41.942833]},"n750":{"id":"n750","loc":[-85.635319,41.940943]},"n751":{"id":"n751","loc":[-85.637057,41.943224]},"n752":{"id":"n752","loc":[-85.636989,41.943296]},"n753":{"id":"n753","loc":[-85.636851,41.943299]},"n754":{"id":"n754","loc":[-85.636848,41.94322]},"n755":{"id":"n755","loc":[-85.636986,41.943217]},"n756":{"id":"n756","loc":[-85.637569,41.943454]},"n757":{"id":"n757","loc":[-85.637437,41.943458]},"n758":{"id":"n758","loc":[-85.637432,41.943384]},"n759":{"id":"n759","loc":[-85.637564,41.94338]},"n76":{"id":"n76","loc":[-85.638098,41.942912]},"n760":{"id":"n760","loc":[-85.637213,41.943378]},"n761":{"id":"n761","loc":[-85.637217,41.943435]},"n762":{"id":"n762","loc":[-85.637235,41.943434]},"n763":{"id":"n763","loc":[-85.637237,41.943465]},"n764":{"id":"n764","loc":[-85.637424,41.943459]},"n765":{"id":"n765","loc":[-85.637418,41.943371]},"n766":{"id":"n766","loc":[-85.638094,41.943149]},"n767":{"id":"n767","loc":[-85.638096,41.943201]},"n768":{"id":"n768","loc":[-85.638041,41.943202]},"n769":{"id":"n769","loc":[-85.638042,41.943216]},"n77":{"id":"n77","loc":[-85.637705,41.942913]},"n770":{"id":"n770","loc":[-85.637927,41.943218]},"n771":{"id":"n771","loc":[-85.637926,41.943201]},"n772":{"id":"n772","loc":[-85.637897,41.943201]},"n773":{"id":"n773","loc":[-85.637896,41.943155]},"n774":{"id":"n774","loc":[-85.637962,41.943153]},"n775":{"id":"n775","loc":[-85.637962,41.943134]},"n776":{"id":"n776","loc":[-85.638017,41.943132]},"n777":{"id":"n777","loc":[-85.638018,41.943151]},"n778":{"id":"n778","loc":[-85.638045,41.943289]},"n779":{"id":"n779","loc":[-85.638048,41.943363]},"n78":{"id":"n78","loc":[-85.637705,41.942834]},"n780":{"id":"n780","loc":[-85.637842,41.943367]},"n781":{"id":"n781","loc":[-85.637839,41.943296]},"n782":{"id":"n782","loc":[-85.637896,41.943295]},"n783":{"id":"n783","loc":[-85.637897,41.943314]},"n784":{"id":"n784","loc":[-85.637957,41.943312]},"n785":{"id":"n785","loc":[-85.637957,41.943291]},"n786":{"id":"n786","loc":[-85.637816,41.943375]},"n787":{"id":"n787","loc":[-85.637815,41.943416]},"n788":{"id":"n788","loc":[-85.637715,41.943415]},"n789":{"id":"n789","loc":[-85.637716,41.943374]},"n79":{"id":"n79","loc":[-85.638071,41.942298]},"n790":{"id":"n790","loc":[-85.637912,41.943545]},"n791":{"id":"n791","loc":[-85.637909,41.943479]},"n792":{"id":"n792","loc":[-85.637967,41.943477]},"n793":{"id":"n793","loc":[-85.637967,41.94346]},"n794":{"id":"n794","loc":[-85.638077,41.943457]},"n795":{"id":"n795","loc":[-85.638078,41.943473]},"n796":{"id":"n796","loc":[-85.638124,41.943471]},"n797":{"id":"n797","loc":[-85.638126,41.943514]},"n798":{"id":"n798","loc":[-85.638079,41.943515]},"n799":{"id":"n799","loc":[-85.638079,41.943532]},"n8":{"id":"n8","loc":[-85.635241,41.941948]},"n80":{"id":"n80","loc":[-85.638074,41.942431]},"n800":{"id":"n800","loc":[-85.638028,41.943534]},"n801":{"id":"n801","loc":[-85.638028,41.943542]},"n802":{"id":"n802","loc":[-85.638845,41.942983]},"n803":{"id":"n803","loc":[-85.638846,41.94305]},"n804":{"id":"n804","loc":[-85.638661,41.943052]},"n805":{"id":"n805","loc":[-85.63866,41.942984]},"n806":{"id":"n806","loc":[-85.638579,41.942753]},"n807":{"id":"n807","loc":[-85.638445,41.942755]},"n808":{"id":"n808","loc":[-85.638452,41.942978]},"n809":{"id":"n809","loc":[-85.638545,41.942976]},"n81":{"id":"n81","loc":[-85.637836,41.942433]},"n810":{"id":"n810","loc":[-85.638543,41.942935]},"n811":{"id":"n811","loc":[-85.638571,41.942934]},"n812":{"id":"n812","loc":[-85.63857,41.942901]},"n813":{"id":"n813","loc":[-85.638611,41.9429]},"n814":{"id":"n814","loc":[-85.638607,41.942769]},"n815":{"id":"n815","loc":[-85.63858,41.94277]},"n816":{"id":"n816","loc":[-85.638597,41.942614]},"n817":{"id":"n817","loc":[-85.638601,41.94273]},"n818":{"id":"n818","loc":[-85.638686,41.942731]},"n819":{"id":"n819","loc":[-85.638689,41.942917]},"n82":{"id":"n82","loc":[-85.637835,41.94242]},"n820":{"id":"n820","loc":[-85.638558,41.943018]},"n821":{"id":"n821","loc":[-85.638243,41.943019]},"n822":{"id":"n822","loc":[-85.637536,41.943887]},"n823":{"id":"n823","loc":[-85.63749,41.943926]},"n824":{"id":"n824","loc":[-85.63743,41.943886]},"n825":{"id":"n825","loc":[-85.637476,41.943847]},"n826":{"id":"n826","loc":[-85.637527,41.943846]},"n827":{"id":"n827","loc":[-85.637141,41.943728]},"n828":{"id":"n828","loc":[-85.637201,41.943755]},"n829":{"id":"n829","loc":[-85.636987,41.943608]},"n83":{"id":"n83","loc":[-85.63776,41.942421]},"n830":{"id":"n830","loc":[-85.637441,41.943807]},"n831":{"id":"n831","loc":[-85.637673,41.94399]},"n832":{"id":"n832","loc":[-85.637783,41.944137]},"n833":{"id":"n833","loc":[-85.63845,41.944333]},"n834":{"id":"n834","loc":[-85.638159,41.944248]},"n835":{"id":"n835","loc":[-85.637859,41.94416]},"n836":{"id":"n836","loc":[-85.638685,41.944542]},"n837":{"id":"n837","loc":[-85.638714,41.944611]},"n838":{"id":"n838","loc":[-85.638711,41.944757]},"n839":{"id":"n839","loc":[-85.638774,41.945069]},"n84":{"id":"n84","loc":[-85.637758,41.942339]},"n840":{"id":"n840","loc":[-85.638742,41.945205]},"n841":{"id":"n841","loc":[-85.640267,41.942403]},"n842":{"id":"n842","loc":[-85.640154,41.942404]},"n843":{"id":"n843","loc":[-85.640152,41.942249]},"n844":{"id":"n844","loc":[-85.640266,41.942248]},"n845":{"id":"n845","loc":[-85.640366,41.942599]},"n846":{"id":"n846","loc":[-85.640362,41.942192]},"n847":{"id":"n847","loc":[-85.640146,41.942191]},"n848":{"id":"n848","loc":[-85.640122,41.942196]},"n849":{"id":"n849","loc":[-85.640108,41.942211]},"n85":{"id":"n85","loc":[-85.637836,41.942339]},"n850":{"id":"n850","loc":[-85.640101,41.942236]},"n851":{"id":"n851","loc":[-85.640103,41.94241]},"n852":{"id":"n852","loc":[-85.64011,41.942435]},"n853":{"id":"n853","loc":[-85.640126,41.942445]},"n854":{"id":"n854","loc":[-85.640153,41.942451]},"n855":{"id":"n855","loc":[-85.640183,41.942452]},"n856":{"id":"n856","loc":[-85.640364,41.942452]},"n857":{"id":"n857","loc":[-85.640007,41.942452]},"n858":{"id":"n858","loc":[-85.639449,41.942461]},"n859":{"id":"n859","loc":[-85.640049,41.942391]},"n86":{"id":"n86","loc":[-85.637835,41.942301]},"n860":{"id":"n860","loc":[-85.640052,41.942503]},"n861":{"id":"n861","loc":[-85.639575,41.94251]},"n862":{"id":"n862","loc":[-85.639572,41.942398]},"n863":{"id":"n863","loc":[-85.638782,41.942227]},"n864":{"id":"n864","loc":[-85.63843,41.942226]},"n865":{"id":"n865","loc":[-85.63823,41.942183]},"n866":{"id":"n866","loc":[-85.638363,41.942216],"tags":{"barrier":"gate"}},"n867":{"id":"n867","loc":[-85.6384,41.942223]},"n868":{"id":"n868","loc":[-85.636042,41.942797]},"n869":{"id":"n869","loc":[-85.636308,41.942752]},"n87":{"id":"n87","loc":[-85.637566,41.942367]},"n870":{"id":"n870","loc":[-85.636516,41.942729]},"n871":{"id":"n871","loc":[-85.636782,41.942712]},"n872":{"id":"n872","loc":[-85.636944,41.942706]},"n873":{"id":"n873","loc":[-85.63704,41.942706]},"n874":{"id":"n874","loc":[-85.637237,41.942703]},"n875":{"id":"n875","loc":[-85.637553,41.9427]},"n876":{"id":"n876","loc":[-85.638236,41.942697]},"n877":{"id":"n877","loc":[-85.636284,41.942781]},"n878":{"id":"n878","loc":[-85.636551,41.942641]},"n879":{"id":"n879","loc":[-85.633914,41.943693]},"n88":{"id":"n88","loc":[-85.637566,41.94241]},"n880":{"id":"n880","loc":[-85.63389,41.943708]},"n881":{"id":"n881","loc":[-85.633866,41.943686]},"n882":{"id":"n882","loc":[-85.63389,41.943671]},"n883":{"id":"n883","loc":[-85.633857,41.943609]},"n884":{"id":"n884","loc":[-85.634858,41.944474]},"n885":{"id":"n885","loc":[-85.633988,41.943234]},"n886":{"id":"n886","loc":[-85.633999,41.943485]},"n887":{"id":"n887","loc":[-85.634109,41.943449],"tags":{"emergency":"fire_hydrant"}},"n888":{"id":"n888","loc":[-85.635728,41.942655],"tags":{"emergency":"fire_hydrant"}},"n889":{"id":"n889","loc":[-85.636499,41.942845],"tags":{"man_made":"flagpole"}},"n89":{"id":"n89","loc":[-85.637455,41.94241]},"n890":{"id":"n890","loc":[-85.636197,41.943073]},"n891":{"id":"n891","loc":[-85.636227,41.943073]},"n892":{"id":"n892","loc":[-85.637433,41.942933],"tags":{"addr:city":"Three Rivers","addr:housenumber":"401","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"restaurant","cuisine":"pizza","name":"Pizza Hut"}},"n893":{"id":"n893","loc":[-85.637907,41.942879],"tags":{"amenity":"car_wash"}},"n894":{"id":"n894","loc":[-85.637661,41.943018]},"n895":{"id":"n895","loc":[-85.636933,41.942733],"tags":{"emergency":"fire_hydrant"}},"n896":{"id":"n896","loc":[-85.637661,41.94304]},"n897":{"id":"n897","loc":[-85.637562,41.943041]},"n898":{"id":"n898","loc":[-85.637556,41.942725]},"n899":{"id":"n899","loc":[-85.637656,41.942724]},"n9":{"id":"n9","loc":[-85.635159,41.941926]},"n90":{"id":"n90","loc":[-85.637454,41.942367]},"n900":{"id":"n900","loc":[-85.637657,41.942779]},"n901":{"id":"n901","loc":[-85.637983,41.942777]},"n902":{"id":"n902","loc":[-85.637982,41.942616]},"n903":{"id":"n903","loc":[-85.637777,41.942778]},"n904":{"id":"n904","loc":[-85.637775,41.942699]},"n905":{"id":"n905","loc":[-85.637772,41.942618]},"n906":{"id":"n906","loc":[-85.637982,41.942698]},"n907":{"id":"n907","loc":[-85.637941,41.942378],"tags":{"addr:city":"Three Rivers","addr:housenumber":"416","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","name":"Gem Pawnbroker","shop":"pawnbroker"}},"n908":{"id":"n908","loc":[-85.637515,41.942394],"tags":{"second_hand":"only","shop":"car"}},"n909":{"id":"n909","loc":[-85.638743,41.942374],"tags":{"addr:city":"Three Rivers","addr:housenumber":"500","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","name":"William Towing","service:vehicle:towing":"yes","service:vehicle:tyres":"yes","shop":"car_repair"}},"n91":{"id":"n91","loc":[-85.637565,41.942341]},"n910":{"id":"n910","loc":[-85.638594,41.942357]},"n911":{"id":"n911","loc":[-85.634312,41.943562],"tags":{"addr:city":"Three Rivers","addr:housenumber":"145","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"cafe","cuisine":"coffee_shop","name":"L.A.'s Coffee Cafe","outdoor_seating":"yes"}},"n912":{"id":"n912","loc":[-85.634404,41.943512]},"n913":{"id":"n913","loc":[-85.634391,41.943519],"tags":{"entrance":"yes"}},"n914":{"id":"n914","loc":[-85.634259,41.943538],"tags":{"entrance":"yes"}},"n915":{"id":"n915","loc":[-85.634247,41.943528]},"n916":{"id":"n916","loc":[-85.633747,41.943322],"tags":{"addr:city":"Three Rivers","addr:housenumber":"132","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","name":"Preferred Insurance Services","office":"insurance"}},"n917":{"id":"n917","loc":[-85.63299,41.943686],"tags":{"addr:city":"Three Rivers","addr:housenumber":"101","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Lynn's Garage","service:vehicle:tyres":"yes","shop":"car_repair"}},"n918":{"id":"n918","loc":[-85.633438,41.944883]},"n919":{"id":"n919","loc":[-85.633265,41.944983]},"n92":{"id":"n92","loc":[-85.637481,41.942341]},"n920":{"id":"n920","loc":[-85.633315,41.945027]},"n921":{"id":"n921","loc":[-85.633376,41.944827]},"n922":{"id":"n922","loc":[-85.633199,41.944922]},"n923":{"id":"n923","loc":[-85.633316,41.944772]},"n924":{"id":"n924","loc":[-85.633147,41.944867]},"n925":{"id":"n925","loc":[-85.633261,41.944719]},"n926":{"id":"n926","loc":[-85.633096,41.944812]},"n927":{"id":"n927","loc":[-85.633191,41.944645]},"n928":{"id":"n928","loc":[-85.632981,41.94476]},"n929":{"id":"n929","loc":[-85.633062,41.94483]},"n93":{"id":"n93","loc":[-85.637481,41.94226]},"n930":{"id":"n930","loc":[-85.633146,41.944602]},"n931":{"id":"n931","loc":[-85.632969,41.944703]},"n932":{"id":"n932","loc":[-85.633008,41.944745]},"n933":{"id":"n933","loc":[-85.633088,41.944545]},"n934":{"id":"n934","loc":[-85.632868,41.944655]},"n935":{"id":"n935","loc":[-85.632941,41.944718]},"n936":{"id":"n936","loc":[-85.633028,41.944483]},"n937":{"id":"n937","loc":[-85.632817,41.944605]},"n938":{"id":"n938","loc":[-85.632923,41.944373]},"n939":{"id":"n939","loc":[-85.632692,41.944485]},"n94":{"id":"n94","loc":[-85.637565,41.94226]},"n940":{"id":"n940","loc":[-85.632871,41.944316]},"n941":{"id":"n941","loc":[-85.632655,41.944421]},"n942":{"id":"n942","loc":[-85.632711,41.944478]},"n943":{"id":"n943","loc":[-85.632825,41.94426]},"n944":{"id":"n944","loc":[-85.632606,41.944363]},"n945":{"id":"n945","loc":[-85.63275,41.94418]},"n946":{"id":"n946","loc":[-85.632588,41.944256]},"n947":{"id":"n947","loc":[-85.632611,41.944279]},"n948":{"id":"n948","loc":[-85.632548,41.944306]},"n949":{"id":"n949","loc":[-85.632512,41.944406]},"n95":{"id":"n95","loc":[-85.637188,41.942217]},"n950":{"id":"n950","loc":[-85.632565,41.944463]},"n951":{"id":"n951","loc":[-85.632579,41.944456]},"n952":{"id":"n952","loc":[-85.632634,41.944518]},"n953":{"id":"n953","loc":[-85.632686,41.944569]},"n954":{"id":"n954","loc":[-85.632745,41.944537]},"n955":{"id":"n955","loc":[-85.632659,41.944587]},"n956":{"id":"n956","loc":[-85.632778,41.944705]},"n957":{"id":"n957","loc":[-85.632815,41.944301],"tags":{"addr:city":"Three Rivers","addr:housenumber":"5","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Access Point Employment","office":"employment_agency"}},"n958":{"id":"n958","loc":[-85.6332,41.944174],"tags":{"addr:city":"Three Rivers","addr:housenumber":"6","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Paisley Emporium","shop":"second_hand"}},"n959":{"id":"n959","loc":[-85.633578,41.944568],"tags":{"addr:city":"Three Rivers","addr:housenumber":"22","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Lowry's Books","shop":"books"}},"n96":{"id":"n96","loc":[-85.637189,41.942303]},"n960":{"id":"n960","loc":[-85.63344,41.944443],"tags":{"addr:city":"Three Rivers","addr:housenumber":"16","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"restaurant","cuisine":"pizza","name":"Paisano's Bar and Grill"}},"n961":{"id":"n961","loc":[-85.633009,41.944542],"tags":{"addr:city":"Three Rivers","addr:housenumber":"13","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"cafe","cuisine":"american","internet_access":"yes","name":"Main Street Cafe"}},"n962":{"id":"n962","loc":[-85.633674,41.944682],"tags":{"addr:city":"Three Rivers","addr:housenumber":"28","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","leisure":"fitness_centre","name":"Main Street Fitness"}},"n963":{"id":"n963","loc":[-85.633376,41.944868],"tags":{"addr:city":"Three Rivers","addr:housenumber":"27","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","leisure":"fitness_centre","name":"Main Street Barbell"}},"n964":{"id":"n964","loc":[-85.633366,41.944783]},"n965":{"id":"n965","loc":[-85.633296,41.94482]},"n966":{"id":"n966","loc":[-85.633214,41.94487]},"n967":{"id":"n967","loc":[-85.633005,41.944988]},"n968":{"id":"n968","loc":[-85.633269,41.944816]},"n969":{"id":"n969","loc":[-85.633215,41.944842]},"n97":{"id":"n97","loc":[-85.637299,41.942302]},"n970":{"id":"n970","loc":[-85.633245,41.944871]},"n971":{"id":"n971","loc":[-85.633296,41.944845]},"n972":{"id":"n972","loc":[-85.633254,41.944845],"tags":{"natural":"tree"}},"n973":{"id":"n973","loc":[-85.633557,41.945515]},"n974":{"id":"n974","loc":[-85.633279,41.945246]},"n975":{"id":"n975","loc":[-85.63324,41.945226]},"n976":{"id":"n976","loc":[-85.6332,41.945213]},"n977":{"id":"n977","loc":[-85.633133,41.945164]},"n978":{"id":"n978","loc":[-85.63312,41.945132]},"n979":{"id":"n979","loc":[-85.633095,41.945081]},"n98":{"id":"n98","loc":[-85.637299,41.942314]},"n980":{"id":"n980","loc":[-85.633064,41.945047]},"n981":{"id":"n981","loc":[-85.632739,41.944742]},"n982":{"id":"n982","loc":[-85.633281,41.945026]},"n983":{"id":"n983","loc":[-85.633155,41.944903]},"n984":{"id":"n984","loc":[-85.633079,41.944829]},"n985":{"id":"n985","loc":[-85.63304,41.944853]},"n986":{"id":"n986","loc":[-85.632949,41.944776]},"n987":{"id":"n987","loc":[-85.632921,41.944725]},"n988":{"id":"n988","loc":[-85.632859,41.944673]},"n989":{"id":"n989","loc":[-85.632895,41.94505]},"n99":{"id":"n99","loc":[-85.637396,41.942313]},"n990":{"id":"n990","loc":[-85.633336,41.945138]},"n991":{"id":"n991","loc":[-85.633466,41.945265]},"n992":{"id":"n992","loc":[-85.633367,41.945327]},"n993":{"id":"n993","loc":[-85.633163,41.945189]},"n994":{"id":"n994","loc":[-85.633678,41.945309]},"n995":{"id":"n995","loc":[-85.633619,41.945261]},"n996":{"id":"n996","loc":[-85.63355,41.945301]},"n997":{"id":"n997","loc":[-85.633607,41.945352]},"n998":{"id":"n998","loc":[-85.633579,41.945327],"tags":{"entrance":"yes"}},"n999":{"id":"n999","loc":[-85.633445,41.945404]},"r2":{"id":"r2","members":[{"id":"w225","role":"outer","type":"way"}],"tags":{"type":"multipolygon","waterway":"riverbank"}},"r5":{"id":"r5","members":[{"id":"w642","role":"outer","type":"way"}],"tags":{"admin_level":"8","border_type":"city","boundary":"administrative","name":"Three Rivers","place":"city","type":"boundary"}},"w1":{"id":"w1","nodes":["n5","n1797"],"tags":{"highway":"residential","name":"12th Avenue"}},"w10":{"id":"w10","nodes":["n54","n55","n56","n57","n891","n890","n54"],"tags":{"building":"yes"}},"w100":{"id":"w100","nodes":["n451","n915","n452"],"tags":{"highway":"footway"}},"w101":{"id":"w101","nodes":["n461","n462","n463","n464","n465","n466"],"tags":{"barrier":"fence"}},"w102":{"id":"w102","nodes":["n467","n468","n469","n470","n472","n467"],"tags":{"amenity":"parking"}},"w103":{"id":"w103","nodes":["n2597","n2444","n471","n472"],"tags":{"highway":"footway"}},"w104":{"id":"w104","nodes":["n473","n474","n325"],"tags":{"footway":"sidewalk","highway":"footway"}},"w105":{"id":"w105","nodes":["n475","n324","n325"],"tags":{"footway":"sidewalk","highway":"footway"}},"w106":{"id":"w106","nodes":["n886","n452","n476"],"tags":{"footway":"sidewalk","highway":"footway"}},"w107":{"id":"w107","nodes":["n485","n4678","n486","n18"],"tags":{"highway":"service"}},"w108":{"id":"w108","nodes":["n300","n487","n488","n489","n490"],"tags":{"highway":"footway"}},"w109":{"id":"w109","nodes":["n490","n491"],"tags":{"highway":"footway"}},"w11":{"id":"w11","nodes":["n58","n63","n59","n315","n60"],"tags":{"highway":"service"}},"w110":{"id":"w110","nodes":["n492","n493","n494","n495","n496","n497","n492"],"tags":{"building":"yes"}},"w111":{"id":"w111","nodes":["n498","n499","n511"],"tags":{"highway":"service"}},"w112":{"id":"w112","nodes":["n510","n500","n501","n502","n503","n504","n505","n506","n507","n508","n509"],"tags":{"highway":"service"}},"w113":{"id":"w113","nodes":["n511","n510"],"tags":{"covered":"yes","highway":"service"}},"w114":{"id":"w114","nodes":["n512","n513","n514","n515","n512"],"tags":{"building":"yes"}},"w115":{"id":"w115","nodes":["n516","n517","n518","n519","n516"],"tags":{"building":"yes"}},"w116":{"id":"w116","nodes":["n520","n521","n522","n523","n520"],"tags":{"building":"yes"}},"w117":{"id":"w117","nodes":["n524","n525","n526","n527","n528","n529","n530","n531","n532","n533","n534","n535","n524"],"tags":{"building":"yes"}},"w118":{"id":"w118","nodes":["n536","n537","n538","n539","n536"],"tags":{"building":"yes"}},"w119":{"id":"w119","nodes":["n540","n541","n542","n543","n544","n545","n546","n547","n540"],"tags":{"building":"yes"}},"w12":{"id":"w12","nodes":["n61","n314","n70","n62","n63"],"tags":{"highway":"service"}},"w120":{"id":"w120","nodes":["n548","n549","n550","n551","n552","n553","n554","n555","n556","n557","n548"],"tags":{"building":"yes"}},"w121":{"id":"w121","nodes":["n558","n559","n560","n561","n562","n563","n564","n565","n558"],"tags":{"building":"yes"}},"w122":{"id":"w122","nodes":["n566","n567","n568","n569","n566"],"tags":{"building":"yes"}},"w123":{"id":"w123","nodes":["n570","n571","n572","n573","n570"],"tags":{"building":"yes"}},"w124":{"id":"w124","nodes":["n574","n575","n576","n577","n574"],"tags":{"building":"yes"}},"w125":{"id":"w125","nodes":["n578","n579","n580","n581","n578"],"tags":{"building":"yes"}},"w126":{"id":"w126","nodes":["n582","n583","n584","n585","n582"],"tags":{"building":"yes"}},"w127":{"id":"w127","nodes":["n586","n587","n588","n589","n590","n591","n592","n593","n586"],"tags":{"building":"yes"}},"w128":{"id":"w128","nodes":["n594","n595","n596","n597","n598","n599","n600","n601","n594"],"tags":{"building":"yes"}},"w129":{"id":"w129","nodes":["n309","n602","n603"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w13":{"id":"w13","nodes":["n64","n65","n66","n67","n68","n69","n64"],"tags":{"amenity":"parking"}},"w130":{"id":"w130","nodes":["n603","n604"],"tags":{"footway":"sidewalk","highway":"footway"}},"w131":{"id":"w131","nodes":["n604","n605","n606"],"tags":{"footway":"sidewalk","highway":"footway"}},"w132":{"id":"w132","nodes":["n606","n607"],"tags":{"footway":"sidewalk","highway":"footway"}},"w133":{"id":"w133","nodes":["n607","n610","n608","n603"],"tags":{"footway":"sidewalk","highway":"footway"}},"w134":{"id":"w134","nodes":["n609","n610","n611"],"tags":{"highway":"service","service":"driveway","surface":"unpaved"}},"w135":{"id":"w135","nodes":["n244","n245","n246"],"tags":{"highway":"service"}},"w136":{"id":"w136","nodes":["n612","n613","n614","n615","n612"],"tags":{"amenity":"shelter"}},"w137":{"id":"w137","nodes":["n2779","n2788","n2776","n2778","n2775","n2787","n2440","n2437","n629","n2438","n630","n2439","n2407","n2408","n2409"],"tags":{"highway":"residential","name":"Foster Street"}},"w138":{"id":"w138","nodes":["n2779","n625","n626","n627"],"tags":{"highway":"residential","name":"Foster Street","oneway":"yes"}},"w139":{"id":"w139","nodes":["n630","n631","n632","n2437"],"tags":{"highway":"service"}},"w14":{"id":"w14","nodes":["n71","n72","n73","n74","n71"],"tags":{"building":"yes"}},"w140":{"id":"w140","nodes":["n643","n637","n715","n2410"],"tags":{"highway":"footway","name":"Mural Mall"}},"w141":{"id":"w141","nodes":["n639","n2516"],"tags":{"barrier":"wall"}},"w142":{"id":"w142","nodes":["n640","n641","n645","n642","n660","n643","n644"],"tags":{"highway":"service"}},"w143":{"id":"w143","nodes":["n646","n647"],"tags":{"highway":"service"}},"w144":{"id":"w144","nodes":["n654","n655","n656"],"tags":{"barrier":"wall"}},"w145":{"id":"w145","nodes":["n665","n666","n667"],"tags":{"barrier":"wall"}},"w146":{"id":"w146","nodes":["n2727","n662","n2719"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w147":{"id":"w147","nodes":["n2725","n674"],"tags":{"highway":"service","oneway":"yes"}},"w148":{"id":"w148","nodes":["n2464","n2460","n2454","n684","n2455","n2464"],"tags":{"building":"yes"}},"w149":{"id":"w149","nodes":["n2456","n685","n686","n687","n2456"],"tags":{"building":"yes"}},"w15":{"id":"w15","nodes":["n75","n76","n77","n78","n75"],"tags":{"building":"yes"}},"w150":{"id":"w150","nodes":["n685","n688","n689","n690","n691","n692","n686","n685"],"tags":{"building":"yes"}},"w151":{"id":"w151","nodes":["n688","n693","n694","n689","n688"],"tags":{"building":"yes"}},"w152":{"id":"w152","nodes":["n693","n695","n702","n696","n697","n694","n693"],"tags":{"building":"yes"}},"w153":{"id":"w153","nodes":["n695","n698","n699","n700","n701","n702","n695"],"tags":{"building":"yes"}},"w154":{"id":"w154","nodes":["n698","n703","n707","n704","n699","n698"],"tags":{"building":"yes"}},"w155":{"id":"w155","nodes":["n703","n705","n706","n707","n703"],"tags":{"building":"yes"}},"w156":{"id":"w156","nodes":["n705","n708","n709","n706","n705"],"tags":{"building":"yes"}},"w157":{"id":"w157","nodes":["n709","n710","n711","n708","n709"],"tags":{"building":"yes"}},"w158":{"id":"w158","nodes":["n369","n712","n725","n713","n714","n715","n727","n716","n717","n718","n719"],"tags":{"footway":"sidewalk","highway":"footway"}},"w159":{"id":"w159","nodes":["n714","n720","n721"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w16":{"id":"w16","nodes":["n79","n80","n81","n82","n83","n84","n85","n86","n79"],"tags":{"building":"yes"}},"w160":{"id":"w160","nodes":["n729","n721","n722","n964","n723","n724"],"tags":{"footway":"sidewalk","highway":"footway"}},"w161":{"id":"w161","nodes":["n713","n726","n722"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w162":{"id":"w162","nodes":["n727","n2411","n728"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w163":{"id":"w163","nodes":["n729","n730","n731"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w164":{"id":"w164","nodes":["n365","n732","n733","n738"],"tags":{"footway":"sidewalk","highway":"footway"}},"w165":{"id":"w165","nodes":["n724","n734","n367","n735","n736","n737"],"tags":{"footway":"sidewalk","highway":"footway"}},"w166":{"id":"w166","nodes":["n739","n2037","n2038","n2039","n2040","n1623","n2032"],"tags":{"highway":"footway"}},"w167":{"id":"w167","nodes":["n150","n751"],"tags":{"highway":"service"}},"w168":{"id":"w168","nodes":["n752","n753","n754","n755","n752"],"tags":{"building":"yes"}},"w169":{"id":"w169","nodes":["n756","n757","n758","n759","n756"],"tags":{"building":"yes"}},"w17":{"id":"w17","nodes":["n87","n88","n89","n90","n87"],"tags":{"building":"yes"}},"w170":{"id":"w170","nodes":["n760","n761","n762","n763","n764","n765","n760"],"tags":{"building":"yes"}},"w171":{"id":"w171","nodes":["n766","n767","n768","n769","n770","n771","n772","n773","n774","n775","n776","n777","n766"],"tags":{"building":"yes"}},"w172":{"id":"w172","nodes":["n778","n779","n780","n781","n782","n783","n784","n785","n778"],"tags":{"building":"yes"}},"w173":{"id":"w173","nodes":["n786","n787","n788","n789","n786"],"tags":{"building":"yes"}},"w174":{"id":"w174","nodes":["n790","n791","n792","n793","n794","n795","n796","n797","n798","n799","n800","n801","n790"],"tags":{"building":"yes"}},"w175":{"id":"w175","nodes":["n802","n803","n804","n805","n802"],"tags":{"building":"yes"}},"w176":{"id":"w176","nodes":["n806","n807","n808","n809","n810","n811","n812","n813","n814","n815","n806"],"tags":{"building":"yes"}},"w177":{"id":"w177","nodes":["n816","n1140","n817","n818","n819","n820","n821"],"tags":{"highway":"service"}},"w178":{"id":"w178","nodes":["n822","n823","n824","n825","n822"],"tags":{"building":"yes"}},"w179":{"id":"w179","nodes":["n841","n842","n843","n844","n841"],"tags":{"building":"yes"}},"w18":{"id":"w18","nodes":["n91","n92","n93","n94","n91"],"tags":{"building":"yes"}},"w180":{"id":"w180","nodes":["n845","n856","n846"],"tags":{"highway":"service"}},"w181":{"id":"w181","nodes":["n846","n847","n848","n849","n850","n851","n852","n853","n854","n855","n856"],"tags":{"highway":"service","oneway":"yes","service":"drive-through"}},"w182":{"id":"w182","nodes":["n857","n858"],"tags":{"highway":"service"}},"w183":{"id":"w183","nodes":["n859","n860","n861","n862","n859"],"tags":{"amenity":"parking"}},"w184":{"id":"w184","nodes":["n863","n864","n867","n866","n865"],"tags":{"highway":"service"}},"w185":{"id":"w185","nodes":["n883","n884"],"tags":{"barrier":"fence"}},"w186":{"id":"w186","nodes":["n1954","n622","n1955"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w187":{"id":"w187","nodes":["n621","n1954"],"tags":{"highway":"steps","incline":"up","name":"Riverwalk Trail","surface":"wood"}},"w188":{"id":"w188","nodes":["n2274","n2275","n2276","n2277","n2278","n2279","n1953","n621"],"tags":{"highway":"path","name":"Riverwalk Trail","surface":"wood"}},"w189":{"id":"w189","nodes":["n2273","n2274"],"tags":{"highway":"steps","incline":"down","name":"Riverwalk Trail","surface":"wood"}},"w19":{"id":"w19","nodes":["n95","n96","n97","n98","n99","n100","n101","n102","n95"],"tags":{"building":"yes"}},"w190":{"id":"w190","nodes":["n821","n894","n900","n903","n901"],"tags":{"highway":"service"}},"w191":{"id":"w191","nodes":["n896","n897","n898","n899","n900","n894","n896"],"tags":{"amenity":"parking"}},"w192":{"id":"w192","nodes":["n903","n904","n905"],"tags":{"highway":"service"}},"w193":{"id":"w193","nodes":["n901","n906","n902"],"tags":{"highway":"service"}},"w194":{"id":"w194","nodes":["n912","n913"],"tags":{"highway":"footway"}},"w195":{"id":"w195","nodes":["n914","n915"],"tags":{"highway":"footway"}},"w196":{"id":"w196","nodes":["n2466","n918","n919","n920","n2466"],"tags":{"building":"yes"}},"w197":{"id":"w197","nodes":["n918","n921","n922","n919","n918"],"tags":{"building":"yes"}},"w198":{"id":"w198","nodes":["n923","n925","n926","n924","n923"],"tags":{"building":"yes"}},"w199":{"id":"w199","nodes":["n925","n927","n932","n928","n929","n926","n925"],"tags":{"building":"yes"}},"w2":{"id":"w2","nodes":["n3523","n2182","n2160"],"tags":{"highway":"service"}},"w20":{"id":"w20","nodes":["n103","n104","n105","n106","n107","n108","n109","n110","n111","n112","n113","n114","n103"],"tags":{"building":"yes"}},"w200":{"id":"w200","nodes":["n927","n930","n931","n932","n927"],"tags":{"building":"yes"}},"w201":{"id":"w201","nodes":["n930","n933","n934","n935","n931","n930"],"tags":{"building":"yes"}},"w202":{"id":"w202","nodes":["n933","n936","n937","n934","n933"],"tags":{"building":"yes"}},"w203":{"id":"w203","nodes":["n936","n938","n942","n939","n954","n937","n936"],"tags":{"building":"yes"}},"w204":{"id":"w204","nodes":["n938","n940","n941","n942","n938"],"tags":{"building":"yes"}},"w205":{"id":"w205","nodes":["n940","n943","n944","n941","n940"],"tags":{"building":"yes"}},"w206":{"id":"w206","nodes":["n943","n945","n946","n947","n948","n944","n943"],"tags":{"building":"yes"}},"w207":{"id":"w207","nodes":["n944","n949","n950","n951","n941","n944"],"tags":{"building":"yes"}},"w208":{"id":"w208","nodes":["n941","n951","n952","n939","n942","n941"],"tags":{"building":"yes"}},"w209":{"id":"w209","nodes":["n952","n953","n954","n939","n952"],"tags":{"building":"yes"}},"w21":{"id":"w21","nodes":["n115","n116","n117","n118","n115"],"tags":{"building":"yes"}},"w210":{"id":"w210","nodes":["n953","n955","n956","n934","n937","n954","n953"],"tags":{"building":"yes"}},"w211":{"id":"w211","nodes":["n964","n965"],"tags":{"highway":"footway"}},"w212":{"id":"w212","nodes":["n966","n983","n967","n989"],"tags":{"highway":"footway"}},"w213":{"id":"w213","nodes":["n965","n968","n969","n966","n970","n971","n965"],"tags":{"highway":"footway"}},"w214":{"id":"w214","nodes":["n973","n999","n992","n974","n975","n976","n993","n977","n978","n979","n980","n967","n981","n1000","n1001","n1002","n1003","n1004","n1005","n1006","n1007","n1008","n1009"],"tags":{"footway":"sidewalk","highway":"footway"}},"w215":{"id":"w215","nodes":["n978","n982","n983","n984","n985","n986","n987","n988","n981"],"tags":{"highway":"footway"}},"w216":{"id":"w216","nodes":["n976","n990","n991","n992"],"tags":{"highway":"footway"}},"w217":{"id":"w217","nodes":["n998","n999"],"tags":{"highway":"footway"}},"w218":{"id":"w218","nodes":["n1019","n1020","n1021","n1022","n731","n728","n1023","n1025","n1024","n1019"],"tags":{"footway":"sidewalk","highway":"footway"}},"w219":{"id":"w219","nodes":["n719","n1026","n1027"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w22":{"id":"w22","nodes":["n119","n120","n121","n122","n119"],"tags":{"building":"yes"}},"w220":{"id":"w220","nodes":["n1027","n1028","n1019"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w221":{"id":"w221","nodes":["n2080","n1828","n1863","n1829"],"tags":{"highway":"tertiary","name":"Constantine Street"}},"w222":{"id":"w222","nodes":["n1029","n1030","n1031"],"tags":{"highway":"service"}},"w223":{"id":"w223","nodes":["n2213","n2171","n2183","n2180","n2205","n2177","n2179","n2218","n2200","n2188","n2169","n2196","n2162","n2170","n2211","n2216","n2204","n2220","n2164","n2210","n2217","n2189","n460","n453","n2282"],"tags":{"name":"Rocky River","waterway":"river"}},"w224":{"id":"w224","nodes":["n3750","n3751","n3752"],"tags":{"highway":"service","service":"alley","surface":"unpaved"}},"w225":{"id":"w225","nodes":["n2134","n2127","n2313","n2109","n2112","n2129","n2156","n2146","n2126","n2153","n2288","n2283","n2284","n2131","n2286","n2287","n2285","n2132","n2140","n2289","n2122","n2114","n2149","n2119","n2106","n2111","n2145","n2113","n2117","n2159","n2143","n2123","n2142","n2116","n2154","n2139","n2150","n2157","n2120","n2138","n2130","n2136","n2155","n2107","n2141","n2124","n3754","n2121","n2105","n2108","n3755","n2128","n2110","n2152","n2125","n2135","n2186","n2115","n2144","n2137","n2133","n2148","n2118","n1871","n1875","n1872","n2041","n1873","n2042","n1874","n1884","n1870","n2151","n2147","n2158","n2104","n2134"]},"w226":{"id":"w226","nodes":["n2243","n2280","n2244","n2245","n2246","n2247","n1931","n1932","n1933","n1934","n1935","n1936","n1937","n1938","n4681","n1939","n1940","n1941","n1942","n1943","n1944","n1945","n1946","n1947"],"tags":{"highway":"path","name":"Riverwalk Trail","surface":"asphalt","width":"3"}},"w227":{"id":"w227","nodes":["n2994","n3012","n3011","n2958"],"tags":{"highway":"secondary","name":"Main Street"}},"w228":{"id":"w228","nodes":["n2747","n2762","n2757","n2746","n2761","n2758","n2760","n2755","n2749","n2691","n1028","n2432","n2414","n2413","n2412","n2411","n2410","n720","n726","n370","n368","n2748"],"tags":{"highway":"primary","name":"Main Street"}},"w229":{"id":"w229","nodes":["n2083","n2103","n2102","n2084","n2085","n2086","n2087","n2242","n471","n324","n2101","n332","n1868"],"tags":{"name":"Conrail Railroad","railway":"rail"}},"w23":{"id":"w23","nodes":["n123","n124","n125","n126","n123"],"tags":{"building":"yes"}},"w230":{"id":"w230","nodes":["n2232","n2236","n2231","n2230","n2226","n2241","n2237","n2227","n1182","n2233","n2228","n2229","n1183","n2234","n19","n1891","n20","n2223","n2224","n2238","n2235","n2240","n2225","n2239"],"tags":{"name":"Saint Joseph River","waterway":"river"}},"w231":{"id":"w231","nodes":["n456","n1036","n1037","n1038"],"tags":{"barrier":"wall"}},"w232":{"id":"w232","nodes":["n1034","n1039","n1040"],"tags":{"barrier":"wall"}},"w233":{"id":"w233","nodes":["n1041","n1042","n1043","n1044","n1045","n1046","n1041"],"tags":{"access":"private","leisure":"swimming_pool"}},"w234":{"id":"w234","nodes":["n1047","n1048"],"tags":{"barrier":"hedge"}},"w235":{"id":"w235","nodes":["n1049","n1050","n1051","n1052","n1049"],"tags":{"building":"yes"}},"w236":{"id":"w236","nodes":["n1053","n1054","n1055","n1056","n1057","n1058","n1059","n1060","n1053"],"tags":{"building":"yes"}},"w237":{"id":"w237","nodes":["n1061","n1062","n1063","n1064","n1065","n1061"],"tags":{"building":"yes"}},"w238":{"id":"w238","nodes":["n1066","n1067","n1068","n1069","n1070","n1071","n1066"],"tags":{"building":"yes"}},"w239":{"id":"w239","nodes":["n1072","n1073","n1074","n1075","n1072"],"tags":{"building":"yes"}},"w24":{"id":"w24","nodes":["n127","n128","n129","n130","n127"],"tags":{"building":"yes"}},"w240":{"id":"w240","nodes":["n1076","n1077","n1078","n1079","n1080","n1081","n1076"],"tags":{"building":"yes"}},"w241":{"id":"w241","nodes":["n1082","n1083","n1084","n1085","n1082"],"tags":{"building":"yes"}},"w242":{"id":"w242","nodes":["n1086","n1087","n1088","n1089","n1086"],"tags":{"building":"yes"}},"w243":{"id":"w243","nodes":["n1090","n1091","n1092","n1093","n1094","n1095","n1096","n1097","n1090"],"tags":{"building":"yes"}},"w244":{"id":"w244","nodes":["n1098","n1099","n1100","n1101"],"tags":{"barrier":"fence"}},"w245":{"id":"w245","nodes":["n1102","n835","n30","n2590","n35","n29","n2591","n34","n28","n2592","n2312","n32","n2593","n31","n33","n2594","n2595","n1102"],"tags":{"highway":"service"}},"w246":{"id":"w246","nodes":["n1103","n1139","n1104"],"tags":{"barrier":"fence"}},"w247":{"id":"w247","nodes":["n1105","n1106","n1107","n1108","n1109","n1110","n1111","n1112","n1113","n1114","n1105"],"tags":{"building":"yes"}},"w248":{"id":"w248","nodes":["n1115","n1116","n1117","n1118","n1119","n1120","n1115"],"tags":{"building":"yes"}},"w249":{"id":"w249","nodes":["n1121","n1122","n1123","n1124","n1121"],"tags":{"building":"yes"}},"w25":{"id":"w25","nodes":["n131","n132","n133","n134","n135","n136","n137","n138","n139","n140","n141","n142","n131"],"tags":{"building":"yes"}},"w250":{"id":"w250","nodes":["n1125","n1126","n1127","n1128","n1129","n1130","n1131","n1132","n1133","n1134","n1135","n1136","n1125"],"tags":{"building":"yes"}},"w251":{"id":"w251","nodes":["n1137","n1138","n1139"],"tags":{"barrier":"fence"}},"w252":{"id":"w252","nodes":["n876","n1140","n1141"],"tags":{"footway":"sidewalk","highway":"footway"}},"w253":{"id":"w253","nodes":["n1141","n1142","n1143","n1144","n1145","n1146"],"tags":{"footway":"sidewalk","highway":"footway"}},"w254":{"id":"w254","nodes":["n1146","n4743","n1147","n1148"],"tags":{"footway":"sidewalk","highway":"footway"}},"w255":{"id":"w255","nodes":["n1148","n1149","n1150","n1151"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w256":{"id":"w256","nodes":["n1151","n1153","n1154","n1155"],"tags":{"footway":"sidewalk","highway":"footway"}},"w257":{"id":"w257","nodes":["n1155","n1156"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w258":{"id":"w258","nodes":["n1157","n1158"],"tags":{"barrier":"retaining_wall"}},"w259":{"id":"w259","nodes":["n1156","n1161","n1159","n1160","n719"],"tags":{"footway":"sidewalk","highway":"footway"}},"w26":{"id":"w26","nodes":["n143","n608","n144"],"tags":{"highway":"service"}},"w260":{"id":"w260","nodes":["n1162","n1163","n1164","n1165","n1166","n1167","n1168","n1169","n1170","n2528"],"tags":{"highway":"footway"}},"w261":{"id":"w261","nodes":["n1171","n1172","n1173"],"tags":{"barrier":"wall"}},"w262":{"id":"w262","nodes":["n1175","n1176","n1177","n1178","n1179","n1180","n1181","n1175"],"tags":{"natural":"wood"}},"w263":{"id":"w263","nodes":["n1947","n1184","n1948","n1185","n1949","n1957","n1950","n480","n1951","n479","n478","n477","n1952","n1851","n1956","n2248","n619","n618","n2249","n2250","n2251","n617","n2252","n616","n2253","n829","n2254","n827","n828","n2255","n830","n2256","n826","n2257","n831","n2258","n832","n835","n834","n2312","n2267","n2259","n833","n2268","n2260","n836","n2261","n837","n2262","n838","n2263","n2264","n839","n2265","n840","n2266"],"tags":{"highway":"path","name":"Riverwalk Trail","surface":"asphalt","width":"3"}},"w264":{"id":"w264","nodes":["n1186","n1187","n1188","n1189","n1186"],"tags":{"building":"yes"}},"w265":{"id":"w265","nodes":["n1190","n1191","n1192","n1193","n1190"],"tags":{"building":"yes"}},"w266":{"id":"w266","nodes":["n1194","n1195","n1196","n1197","n1198","n1199","n1200","n1201","n1194"],"tags":{"building":"yes"}},"w267":{"id":"w267","nodes":["n1205","n1206","n1207","n1208","n1209","n1210","n1205"],"tags":{"building":"house"}},"w268":{"id":"w268","nodes":["n1211","n1212","n1213","n1214","n1215","n1216","n1217","n1218","n1219","n1220","n1211"],"tags":{"building":"house"}},"w269":{"id":"w269","nodes":["n1221","n1225","n1222","n1223","n1224","n1221"],"tags":{"building":"house"}},"w27":{"id":"w27","nodes":["n145","n147","n146"],"tags":{"highway":"footway"}},"w270":{"id":"w270","nodes":["n1225","n1226","n1227","n1229","n1228"],"tags":{"barrier":"fence"}},"w271":{"id":"w271","nodes":["n1229","n1230"],"tags":{"barrier":"fence"}},"w272":{"id":"w272","nodes":["n1231","n1232","n1233","n1234","n1235","n1236","n1237","n1238","n1231"],"tags":{"building":"house"}},"w273":{"id":"w273","nodes":["n1239","n1240","n1241","n1242","n1243","n1244","n1245","n1246","n1239"],"tags":{"building":"house"}},"w274":{"id":"w274","nodes":["n1247","n1248","n1249","n1250","n1247"],"tags":{"building":"house"}},"w275":{"id":"w275","nodes":["n1251","n1252","n1253","n1254","n1255","n1256","n1251"],"tags":{"building":"house"}},"w276":{"id":"w276","nodes":["n1257","n1258","n1259","n1260","n1257"],"tags":{"building":"shed"}},"w277":{"id":"w277","nodes":["n1261","n1262","n1263","n1264","n1265","n1266","n1267","n1268","n1261"],"tags":{"building":"house"}},"w278":{"id":"w278","nodes":["n1269","n1270","n1271","n1272","n1273","n1274","n1284","n1269"],"tags":{"building":"house"}},"w279":{"id":"w279","nodes":["n1275","n1276","n1277","n1278","n1279","n1280","n1275"],"tags":{"building":"house"}},"w28":{"id":"w28","nodes":["n147","n148"],"tags":{"highway":"footway"}},"w280":{"id":"w280","nodes":["n1281","n1282","n1283","n1284"],"tags":{"barrier":"fence"}},"w281":{"id":"w281","nodes":["n1285","n1286","n1287","n1288","n1285"],"tags":{"building":"house"}},"w282":{"id":"w282","nodes":["n1289","n1290","n1291","n1292","n1293","n1294","n1295","n1296","n1289"],"tags":{"building":"house"}},"w283":{"id":"w283","nodes":["n1297","n1298","n1299","n1300","n1301","n1302","n1297"],"tags":{"access":"private","leisure":"swimming_pool"}},"w284":{"id":"w284","nodes":["n1303","n1304","n1305","n1306","n1307","n1308","n1309","n1310","n1311","n1312","n1303"],"tags":{"building":"house"}},"w285":{"id":"w285","nodes":["n1313","n1314","n1315","n1316","n1313"],"tags":{"building":"house"}},"w286":{"id":"w286","nodes":["n1317","n1318","n1319","n1320","n1321","n1322","n1323","n1324","n1325","n1326","n1327","n1328","n1329","n1330","n1317"],"tags":{"building":"house"}},"w287":{"id":"w287","nodes":["n1331","n1332","n1333","n1334","n1465","n1335","n1336","n1331"],"tags":{"building":"yes"}},"w288":{"id":"w288","nodes":["n1349","n1350","n1351","n1352","n1353","n1354","n1355","n1337","n1338","n1341","n1342","n1343","n1344","n1345","n1346","n1347","n1348","n1339","n1340","n1349"],"tags":{"access":"private","leisure":"swimming_pool"}},"w289":{"id":"w289","nodes":["n1356","n1331"],"tags":{"barrier":"fence"}},"w29":{"id":"w29","nodes":["n149","n874","n150","n151","n897","n898","n875","n152"],"tags":{"highway":"service","oneway":"yes"}},"w290":{"id":"w290","nodes":["n1357","n1358","n1359","n1360","n1357"],"tags":{"building":"shed"}},"w291":{"id":"w291","nodes":["n1358","n1361","n1362"],"tags":{"barrier":"fence"}},"w292":{"id":"w292","nodes":["n1363","n1364","n1365","n1366","n1367","n1368","n1363"],"tags":{"building":"house"}},"w293":{"id":"w293","nodes":["n1369","n1370","n1371","n1372","n1373","n1374","n1369"],"tags":{"leisure":"swimming_pool"}},"w294":{"id":"w294","nodes":["n1367","n1375","n1376","n1377"],"tags":{"barrier":"fence"}},"w295":{"id":"w295","nodes":["n1378","n1379","n1380","n1381","n1378"],"tags":{"building":"house"}},"w296":{"id":"w296","nodes":["n1382","n1383","n1384","n1385","n1386","n1387","n1382"],"tags":{"building":"house"}},"w297":{"id":"w297","nodes":["n1388","n1389","n1390","n1391","n1392","n1393","n1388"],"tags":{"building":"house"}},"w298":{"id":"w298","nodes":["n1394","n1395","n1396","n1397","n1394"],"tags":{"building":"house"}},"w299":{"id":"w299","nodes":["n1398","n1399","n1400","n1401","n1398"],"tags":{"access":"private3","leisure":"swimming_pool"}},"w3":{"id":"w3","nodes":["n1","n2"],"tags":{"highway":"track","name":"Water Street"}},"w30":{"id":"w30","nodes":["n153","n154","n155","n156","n153"],"tags":{"amenity":"parking"}},"w300":{"id":"w300","nodes":["n1402","n1403","n1404","n1405","n1406","n1407","n1408","n1409","n1410","n1411","n1412","n1413","n1402"],"tags":{"building":"house"}},"w301":{"id":"w301","nodes":["n1414","n1415","n1416","n1417","n1414"],"tags":{"building":"garage"}},"w302":{"id":"w302","nodes":["n1406","n1418","n1419","n1403"],"tags":{"barrier":"fence"}},"w303":{"id":"w303","nodes":["n1423","n1424","n1425","n1426","n1427","n1428","n1429","n1430","n1431","n1432","n1423"],"tags":{"building":"house"}},"w304":{"id":"w304","nodes":["n1433","n1434","n1435","n1446","n1436","n1437","n1438","n1439","n1444","n1440","n1441","n1445","n1442","n1443","n1433"],"tags":{"access":"private","leisure":"swimming_pool"}},"w305":{"id":"w305","nodes":["n1447","n1448","n1452","n1453","n1454","n1451","n1449","n1450","n1447"],"tags":{"building":"house"}},"w306":{"id":"w306","nodes":["n1455","n1456","n1457","n1458","n1455"],"tags":{"building":"shed"}},"w307":{"id":"w307","nodes":["n1459","n1460","n1461","n1462","n1459"],"tags":{"building":"shed"}},"w308":{"id":"w308","nodes":["n1463","n1464"],"tags":{"barrier":"fence"}},"w309":{"id":"w309","nodes":["n1465","n1466","n1467","n1468"],"tags":{"barrier":"fence"}},"w31":{"id":"w31","nodes":["n157","n605","n158"],"tags":{"highway":"service"}},"w310":{"id":"w310","nodes":["n1469","n1481","n1463"],"tags":{"barrier":"hedge"}},"w311":{"id":"w311","nodes":["n1470","n1471","n1472","n1473","n1474","n1475","n1480","n1476","n1477","n1478","n1479","n1470"],"tags":{"building":"house"}},"w312":{"id":"w312","nodes":["n1480","n1481"],"tags":{"barrier":"wall"}},"w313":{"id":"w313","nodes":["n1482","n1483","n1484","n1485","n1486","n1487","n1488","n1489","n1490","n1491","n1482"],"tags":{"access":"private","leisure":"swimming_pool"}},"w314":{"id":"w314","nodes":["n1492","n1493","n1494","n1495","n1496","n1497","n1498","n1499","n1500","n1501","n1502","n1503","n1504","n1505","n1492"],"tags":{"building":"house"}},"w315":{"id":"w315","nodes":["n1506","n1507","n1508","n1509","n1510","n1511","n1512","n1513","n1514","n1515","n1506"],"tags":{"building":"house"}},"w316":{"id":"w316","nodes":["n1516","n1517","n1518","n1519","n1520","n1521","n1522","n1523","n1516"],"tags":{"building":"house"}},"w317":{"id":"w317","nodes":["n1524","n1525","n1526","n1527","n1528","n1529","n1530","n1531","n1524"],"tags":{"building":"house"}},"w318":{"id":"w318","nodes":["n1532","n1533"],"tags":{"barrier":"fence"}},"w319":{"id":"w319","nodes":["n1534","n1532","n1535"],"tags":{"barrier":"fence"}},"w32":{"id":"w32","nodes":["n159","n160","n161","n162","n159"],"tags":{"amenity":"parking"}},"w320":{"id":"w320","nodes":["n1536","n1537","n1538","n1539","n1536"],"tags":{"building":"shed"}},"w321":{"id":"w321","nodes":["n1540","n1541","n1542","n1543","n1540"],"tags":{"building":"shed"}},"w322":{"id":"w322","nodes":["n1544","n1545","n1546","n1547","n1544"],"tags":{"building":"shed"}},"w323":{"id":"w323","nodes":["n1548","n1549","n1550","n1551","n1548"],"tags":{"building":"house"}},"w324":{"id":"w324","nodes":["n1552","n1553","n1554","n1555","n1556","n1557","n1558","n1559","n1552"],"tags":{"building":"house"}},"w325":{"id":"w325","nodes":["n1560","n1561","n1562","n1563","n1564","n1565","n1566","n1567","n1560"],"tags":{"building":"house"}},"w326":{"id":"w326","nodes":["n1561","n1568","n1569","n1570"],"tags":{"barrier":"wall"}},"w327":{"id":"w327","nodes":["n1571","n1572"],"tags":{"barrier":"fence"}},"w328":{"id":"w328","nodes":["n1573","n1574","n1575","n1576","n1573"],"tags":{"building":"house"}},"w329":{"id":"w329","nodes":["n1577","n1578","n1579","n1580","n1581","n1582","n1583","n1584","n1585","n1586","n1577"],"tags":{"building":"house"}},"w33":{"id":"w33","nodes":["n157","n163"],"tags":{"highway":"service"}},"w330":{"id":"w330","nodes":["n1587","n1588","n1589","n1590","n1591","n1592","n1593","n1594","n1587"],"tags":{"building":"house"}},"w331":{"id":"w331","nodes":["n1595","n1596","n1597","n1598","n1599","n1600","n1601","n1595"],"tags":{"access":"private","leisure":"swimming_pool"}},"w332":{"id":"w332","nodes":["n1602","n1603","n1604","n1605","n1606","n1607","n1608","n1609","n1611","n1610","n1612","n1613","n1602"],"tags":{"building":"house"}},"w333":{"id":"w333","nodes":["n2018","n1626","n1627","n2017","n2018"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w334":{"id":"w334","nodes":["n2","n3","n2764"],"tags":{"highway":"service","name":"Water Street"}},"w335":{"id":"w335","nodes":["n3","n1628","n1614"],"tags":{"highway":"service"}},"w336":{"id":"w336","nodes":["n3198","n4545","n2747"],"tags":{"highway":"residential","name":"Morris Avenue"}},"w337":{"id":"w337","nodes":["n1629","n3504"],"tags":{"highway":"service","service":"alley","surface":"unpaved"}},"w338":{"id":"w338","nodes":["n1813","n1635","n1814","n1634","n1815","n1632","n1816","n1817"],"tags":{"highway":"service","service":"parking_aisle"}},"w339":{"id":"w339","nodes":["n1827","n4684","n4690","n1842","n4686","n4685","n1826","n1828","n1846","n1645","n1637","n4703","n1641"],"tags":{"highway":"residential","name":"Millard Street"}},"w34":{"id":"w34","nodes":["n164","n165","n166","n171","n866","n172","n167","n168","n169","n910","n170","n164"],"tags":{"amenity":"parking"}},"w340":{"id":"w340","nodes":["n1824","n1825"],"tags":{"highway":"service","service":"parking_aisle"}},"w341":{"id":"w341","nodes":["n1701","n1702","n1703","n1704","n1705","n1706","n1701"],"tags":{"building":"yes"}},"w342":{"id":"w342","nodes":["n1855","n1860","n1856","n1775","n1804","n1776","n1855"],"tags":{"amenity":"parking","fee":"no"}},"w343":{"id":"w343","nodes":["n1757","n1758","n1759","n1760","n1757"],"tags":{"building":"yes"}},"w344":{"id":"w344","nodes":["n1659","n1660","n1661","n1662","n1663","n1664","n1665","n1666","n1659"],"tags":{"building":"school"}},"w345":{"id":"w345","nodes":["n1751","n1752","n1753","n1754","n1755","n1756","n1751"],"tags":{"building":"yes"}},"w346":{"id":"w346","nodes":["n1641","n1676","n1673","n1639","n1810","n1642","n1849","n4759","n1845"],"tags":{"highway":"residential","name":"Douglas Avenue"}},"w347":{"id":"w347","nodes":["n1642","n1643","n1031","n1630","n845","n1631","n816","n1831","n902","n905","n152","n149","n1832","n1850","n878","n1833","n1852","n42","n1834","n61","n60","n1851","n1835"],"tags":{"highway":"primary","name":"Michigan Avenue"}},"w348":{"id":"w348","nodes":["n1650","n1651","n1652","n1653","n1654","n1655","n1656","n1657","n1658","n1650"],"tags":{"leisure":"playground"}},"w349":{"id":"w349","nodes":["n1861","n1818","n1819","n1820","n1821","n1825","n1823","n1639"],"tags":{"highway":"service"}},"w35":{"id":"w35","nodes":["n168","n167","n172"],"tags":{"barrier":"fence","fence_type":"chain_link"}},"w350":{"id":"w350","nodes":["n1783","n1819","n1784","n1857","n1861","n1858","n1783"],"tags":{"amenity":"parking"}},"w351":{"id":"w351","nodes":["n1717","n1718","n1719","n1720","n1717"],"tags":{"building":"yes"}},"w352":{"id":"w352","nodes":["n1743","n1744","n1745","n1746","n1747","n1748","n1749","n1750","n1743"],"tags":{"building":"yes"}},"w353":{"id":"w353","nodes":["n1637","n1636","n1029","n4715","n1630"],"tags":{"highway":"residential","name":"Lincoln Avenue"}},"w354":{"id":"w354","nodes":["n1713","n1714","n1715","n1716","n1713"],"tags":{"building":"yes"}},"w355":{"id":"w355","nodes":["n1689","n1690","n1691","n1692","n1693","n1694","n1695","n1696","n1689"],"tags":{"building":"yes"}},"w356":{"id":"w356","nodes":["n1631","n4717","n1840","n4745","n1841"],"tags":{"highway":"residential","name":"Hook Avenue"}},"w357":{"id":"w357","nodes":["n1737","n1738","n1739","n1740","n1741","n1742","n1737"],"tags":{"building":"yes"}},"w358":{"id":"w358","nodes":["n1707","n1708","n1709","n1710","n1711","n1712","n1707"],"tags":{"building":"yes"}},"w359":{"id":"w359","nodes":["n1829","n4695","n4697","n1843","n4698","n4701","n1638","n4702","n4705","n1636","n4706","n4707","n1633"],"tags":{"highway":"residential","name":"South Street"}},"w36":{"id":"w36","nodes":["n910","n171","n866","n172"],"tags":{"barrier":"fence","fence_type":"chain_link"}},"w360":{"id":"w360","nodes":["n1767","n1768","n1769","n1770","n1771","n1772","n1773","n1774","n1767"],"tags":{"building":"yes"}},"w361":{"id":"w361","nodes":["n1859","n1860","n1804","n1640","n1805","n1817","n1806","n1644","n1811","n1807","n1808","n3419","n1812","n1790","n3418","n3744","n1809","n1813","n1810"],"tags":{"highway":"service"}},"w362":{"id":"w362","nodes":["n1639","n1683","n4710","n1633"],"tags":{"highway":"residential","name":"South Street","oneway":"yes"}},"w363":{"id":"w363","nodes":["n1646","n1647","n1648","n1649","n1646"],"tags":{"leisure":"pitch","pitch":"basketball"}},"w364":{"id":"w364","nodes":["n3820","n3821","n3822","n3823","n3824","n3825","n3826","n3827","n3828","n3829","n3830","n3838","n3839","n3820"],"tags":{"amenity":"school","name":"Three Rivers Middle School"}},"w365":{"id":"w365","nodes":["n1721","n1722","n1723","n1724","n1725","n1726","n1727","n1728","n1729","n1730","n1731","n1732","n1733","n1734","n1735","n1736","n1721"],"tags":{"building":"yes"}},"w366":{"id":"w366","nodes":["n1791","n1792","n1793","n1794","n1795","n1796","n1798","n1799","n1800","n1801","n1802","n1803","n1791"],"tags":{"amenity":"parking"}},"w367":{"id":"w367","nodes":["n1633","n4708","n4711","n1643","n4712","n1838","n4752","n1839"],"tags":{"highway":"residential","name":"Grant Avenue"}},"w368":{"id":"w368","nodes":["n1853","n1687","n1688","n1854","n1853"],"tags":{"amenity":"library","building":"yes","name":"Three Rivers Public Library"}},"w369":{"id":"w369","nodes":["n1777","n1778","n1779","n1780","n1781","n1782","n1777"],"tags":{"amenity":"parking"}},"w37":{"id":"w37","nodes":["n173","n174","n175","n176","n177","n178","n179","n180","n173"],"tags":{"building":"yes"}},"w370":{"id":"w370","nodes":["n1645","n1638","n858","n4718","n1631"],"tags":{"highway":"residential","name":"Hook Avenue"}},"w371":{"id":"w371","nodes":["n3836","n3835","n4624","n3831","n4632","n3834","n3832","n3833","n3830","n3838","n3839","n3837","n3836"],"tags":{"amenity":"school","name":"Three Rivers High School"}},"w372":{"id":"w372","nodes":["n1697","n1698","n1699","n1700","n1697"],"tags":{"building":"yes"}},"w373":{"id":"w373","nodes":["n2891","n1785","n1786","n3394","n1787","n1788","n1789","n1830","n1836","n1837","n1848","n3409","n2891"],"tags":{"amenity":"parking"}},"w374":{"id":"w374","nodes":["n1761","n1762","n1763","n1764","n1765","n1766","n1761"],"tags":{"building":"yes"}},"w375":{"id":"w375","nodes":["n1822","n1823"],"tags":{"highway":"service","service":"parking_aisle"}},"w376":{"id":"w376","nodes":["n1677","n1678","n1679","n1680","n1681","n1682","n1677"],"tags":{"amenity":"parking"}},"w377":{"id":"w377","nodes":["n1676","n1675","n1674","n1673"],"tags":{"highway":"service","oneway":"yes"}},"w378":{"id":"w378","nodes":["n1667","n1668","n1669","n1670","n1671","n1672","n1667"],"tags":{"amenity":"school","name":"Andrews Elementary School"}},"w379":{"id":"w379","nodes":["n1630","n4714","n1847","n4750","n1844"],"tags":{"highway":"residential","name":"Lincoln Avenue"}},"w38":{"id":"w38","nodes":["n181","n182","n183","n185","n184","n181"],"tags":{"building":"yes"}},"w380":{"id":"w380","nodes":["n1683","n3745","n1686","n1633"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w381":{"id":"w381","nodes":["n2022","n2037"],"tags":{"highway":"footway"}},"w382":{"id":"w382","nodes":["n1826","n1863"],"tags":{"highway":"residential"}},"w383":{"id":"w383","nodes":["n2011","n2012","n739","n2013","n2014","n2029","n2011"],"tags":{"amenity":"shelter","building":"yes","shelter_type":"picnic_shelter"}},"w384":{"id":"w384","nodes":["n2064","n2065","n2066","n2067","n2068","n2069","n2070","n2071","n2072","n2073","n2074","n2075","n2076","n2077","n2078","n2079","n2064"],"tags":{"building":"yes"}},"w385":{"id":"w385","nodes":["n1923","n1924","n1925","n1926","n1927","n1928","n1930","n1929","n1923"],"tags":{"natural":"water"}},"w386":{"id":"w386","nodes":["n1827","n14","n1886","n15","n1887","n16","n1888","n18","n17","n1889","n12","n13","n1890","n485","n1864","n11","n10","n2058","n2036","n1865","n2020","n9","n8","n1866","n295","n1867"],"tags":{"highway":"service"}},"w387":{"id":"w387","nodes":["n1846","n1843","n865","n157","n4721","n1831"],"tags":{"highway":"residential","name":"Andrews Street"}},"w388":{"id":"w388","nodes":["n2019","n2020","n2021","n2022","n2023","n2024","n2025","n2026","n2027","n2028","n2029"],"tags":{"highway":"footway"}},"w389":{"id":"w389","nodes":["n2217","n2222","n2221","n2219","n1877","n1879","n1882","n1883","n484","n1885","n483","n1880","n1881","n1878","n1884","n2223"],"tags":{"name":"Rocky River","waterway":"river"}},"w39":{"id":"w39","nodes":["n185","n186","n187"],"tags":{"barrier":"fence"}},"w390":{"id":"w390","nodes":["n2050","n2051","n2052","n2053","n2050"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w391":{"id":"w391","nodes":["n2089","n2090","n2091","n2092","n2093","n2094","n2311","n2095","n2096","n2097","n2098","n1174","n2099","n751","n43","n2062","n4725","n873","n1832"],"tags":{"highway":"residential","name":"Constantine Street"}},"w392":{"id":"w392","nodes":["n1869","n212","n436","n2281","n2081"],"tags":{"highway":"primary","name":"Michigan Avenue"}},"w393":{"id":"w393","nodes":["n1829","n611","n144","n4694","n602","n1832"],"tags":{"highway":"tertiary","name":"Constantine Street"}},"w394":{"id":"w394","nodes":["n1997","n1998","n2000","n1999"],"tags":{"highway":"service","service":"parking_aisle"}},"w395":{"id":"w395","nodes":["n1835","n1869"],"tags":{"bridge":"yes","highway":"primary","name":"Michigan Avenue"}},"w396":{"id":"w396","nodes":["n2000","n2001"],"tags":{"highway":"service","service":"parking_aisle"}},"w397":{"id":"w397","nodes":["n2082","n4688","n1842","n308","n498","n509","n246","n241","n1867","n4645","n293","n1834"],"tags":{"highway":"residential","name":"Spring Street"}},"w398":{"id":"w398","nodes":["n2015","n2016","n2017","n2018","n2015"],"tags":{"building":"yes"}},"w399":{"id":"w399","nodes":["n2062","n45","n2063","n877","n41","n1852"],"tags":{"highway":"service"}},"w4":{"id":"w4","nodes":["n7","n38","n378","n379","n7"],"tags":{"building":"yes"}},"w40":{"id":"w40","nodes":["n188","n189","n190","n191","n192","n193","n188"],"tags":{"building":"house"}},"w400":{"id":"w400","nodes":["n1968","n1969","n1970","n1971","n2007","n1972","n1973","n1978","n1974","n1977","n1976","n1975","n1968"],"tags":{"amenity":"parking"}},"w401":{"id":"w401","nodes":["n1963","n1964"],"tags":{"bridge":"yes","highway":"footway"}},"w402":{"id":"w402","nodes":["n1892","n1893","n1894","n1895","n1896","n1897","n1898","n1899","n1900","n1901","n1902","n1903","n1892"],"tags":{"addr:city":"Three Rivers","addr:housenumber":"112","addr:postcode":"49093","addr:state":"MI","addr:street":"Spring Street","barrier":"fence","name":"Scidmore Park Petting Zoo","tourism":"zoo","zoo":"petting_zoo"}},"w403":{"id":"w403","nodes":["n1957","n1958","n1959","n481","n1960","n482","n1949"],"tags":{"highway":"path"}},"w404":{"id":"w404","nodes":["n2281","n27","n330","n1987","n1988"],"tags":{"highway":"service"}},"w405":{"id":"w405","nodes":["n2249","n2269","n2270","n2271","n2272","n454","n455","n2273"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w406":{"id":"w406","nodes":["n1947","n1624","n1625","n2030","n2033","n4658","n4659","n2031","n2032","n2021"],"tags":{"highway":"footway"}},"w407":{"id":"w407","nodes":["n2034","n2036","n2009"],"tags":{"highway":"footway"}},"w408":{"id":"w408","nodes":["n1964","n1965","n2002","n1966","n21","n1967","n1969"],"tags":{"highway":"footway"}},"w409":{"id":"w409","nodes":["n1904","n1905","n1906","n1907","n1908","n1909","n748","n1910","n747","n1911","n749","n1912","n750","n1913","n1922","n1914","n1921","n1915","n746","n1916","n745","n1917","n744","n1918","n743","n742","n1919","n741","n1920","n740","n1904"],"tags":{"natural":"water"}},"w41":{"id":"w41","nodes":["n194","n195","n196","n197","n198","n199","n200","n201","n202","n203","n204","n205","n194"],"tags":{"building":"house"}},"w410":{"id":"w410","nodes":["n1868","n2088"],"tags":{"bridge":"yes","name":"Conrail Railroad","railway":"rail"}},"w411":{"id":"w411","nodes":["n2010","n2019","n2009","n2008","n2058","n2035","n1961","n1962","n1947","n1963"],"tags":{"highway":"footway"}},"w412":{"id":"w412","nodes":["n2290","n2043","n2044","n2045","n1872","n2041","n1873","n2042","n1874","n2046","n2047","n2048","n2049","n2290"],"tags":{"addr:city":"Three Rivers","addr:housenumber":"112","addr:postcode":"49093","addr:state":"MI","addr:street":"Spring Street","leisure":"park","name":"Scidmore Park"}},"w413":{"id":"w413","nodes":["n1831","n876","n4720","n821","n2089"],"tags":{"highway":"residential","name":"Andrews Street"}},"w414":{"id":"w414","nodes":["n2002","n2003","n2004","n2005","n2006","n2007"],"tags":{"highway":"footway"}},"w415":{"id":"w415","nodes":["n1979","n1980","n1981","n1982","n1979"],"tags":{"amenity":"parking"}},"w416":{"id":"w416","nodes":["n2054","n2055","n2056","n2057","n2054"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w417":{"id":"w417","nodes":["n2291","n2292","n2293","n2294","n2295","n2296","n2297","n2298","n2299","n1098","n2300","n2301","n2302","n2303","n2304","n2059","n2060","n2305","n2307","n2306","n2310","n2308","n2309","n2291"],"tags":{"leisure":"park","name":"Memory Isle Park"}},"w418":{"id":"w418","nodes":["n2033","n2034","n2035"],"tags":{"highway":"footway"}},"w419":{"id":"w419","nodes":["n1983","n1984","n1985","n1986","n1983"],"tags":{"amenity":"parking"}},"w42":{"id":"w42","nodes":["n206","n207","n208","n209","n210","n211","n206"],"tags":{"building":"house"}},"w420":{"id":"w420","nodes":["n1840","n4746","n4748","n1847","n4749","n4755","n1838","n4754","n4756","n1849"],"tags":{"highway":"residential","name":"French Street"}},"w421":{"id":"w421","nodes":["n2337","n2268"],"tags":{"highway":"path"}},"w422":{"id":"w422","nodes":["n2338","n2339","n2320","n2317","n2319","n2318","n2340","n2341","n2342","n2343","n2344","n2345","n2346","n2347","n2348","n2338"],"tags":{"natural":"water"}},"w423":{"id":"w423","nodes":["n2180","n2349","n2350","n2351","n2352","n2404","n2353","n2354","n2355","n2356","n2357","n2358","n2359","n2360","n2361","n2362","n2363","n2364","n2365","n2366","n2370","n2371","n2372","n2373","n2374","n2375","n2377","n2378","n2380","n2381","n2382","n2383","n2386","n2389","n2390","n2391","n2392","n2393","n2396","n2397","n2401","n2402","n2321","n2322","n2323","n2403","n2180"],"tags":{"natural":"wetland"}},"w424":{"id":"w424","nodes":["n2324","n2316","n1841","n2315","n2314","n1844","n1839","n4758","n1845"],"tags":{"highway":"residential","name":"Pealer Street"}},"w425":{"id":"w425","nodes":["n2267","n2337","n2336","n2335","n2334","n2333","n2332","n2331","n2330","n37","n2329","n2328","n2327","n36","n2326","n2325","n2266"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w426":{"id":"w426","nodes":["n2478","n681","n680","n679","n2459","n2467","n2487","n2478"],"tags":{"building":"yes"}},"w427":{"id":"w427","nodes":["n2671","n2672","n2673","n2674","n2671"],"tags":{"building":"yes"}},"w428":{"id":"w428","nodes":["n2483","n2482","n2486","n2489","n2492","n2502","n2495","n2480","n2483"],"tags":{"building":"yes"}},"w429":{"id":"w429","nodes":["n2707","n2708","n2716","n2712","n2714","n2713","n2715","n2711","n2710","n2723","n2709","n2707"],"tags":{"amenity":"parking"}},"w43":{"id":"w43","nodes":["n1955","n1956"],"tags":{"footway":"sidewalk","highway":"footway","name":"Riverwalk Trail"}},"w430":{"id":"w430","nodes":["n2471","n2474","n2484","n2479","n2471"],"tags":{"building":"yes"}},"w431":{"id":"w431","nodes":["n2218","n2434","n2436","n2433","n2435","n2210"],"tags":{"name":"Rocky River","waterway":"river"}},"w432":{"id":"w432","nodes":["n2782","n2532","n2783","n2784","n2782"],"tags":{"amenity":"parking"}},"w433":{"id":"w433","nodes":["n2513","n649","n2520","n2514","n2507","n2513"],"tags":{"building":"yes"}},"w434":{"id":"w434","nodes":["n2470","n2468","n2461","n2465","n2470"],"tags":{"building":"yes"}},"w435":{"id":"w435","nodes":["n2598","n2599","n648","n649","n2520","n2598"],"tags":{"building":"yes"}},"w436":{"id":"w436","nodes":["n2639","n2640","n2641","n2642","n2643","n2644","n2645","n2646","n2647","n2648","n2639"],"tags":{"building":"yes"}},"w437":{"id":"w437","nodes":["n2503","n2512","n2508","n2499","n2503"],"tags":{"building":"yes"}},"w438":{"id":"w438","nodes":["n2440","n2800","n2774","n1"],"tags":{"highway":"residential","name":"Water Street"}},"w439":{"id":"w439","nodes":["n2675","n2676","n2677","n2678","n2675"],"tags":{"building":"yes"}},"w44":{"id":"w44","nodes":["n213","n214","n215","n216","n213"],"tags":{"building":"yes"}},"w440":{"id":"w440","nodes":["n2512","n2503","n2507","n2514","n2512"],"tags":{"building":"yes"}},"w441":{"id":"w441","nodes":["n2554","n2717","n674","n2720","n2798"],"tags":{"highway":"service","oneway":"yes"}},"w442":{"id":"w442","nodes":["n2583","n2596","n2584","n2585","n2595","n2586","n2587","n2588","n2589","n2583"],"tags":{"amenity":"parking"}},"w443":{"id":"w443","nodes":["n2629","n2627","n2628","n2616","n2630","n2629"],"tags":{"building":"yes"}},"w444":{"id":"w444","nodes":["n2717","n2724","n670","n2718","n669","n668","n2722","n2727"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w445":{"id":"w445","nodes":["n2572","n2573"],"tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"}},"w446":{"id":"w446","nodes":["n2603","n2604","n2601","n2605","n2606","n2607","n2603"],"tags":{"building":"yes"}},"w447":{"id":"w447","nodes":["n2780","n2777","n628","n624","n2779"],"tags":{"highway":"residential","name":"Foster Street","oneway":"yes"}},"w448":{"id":"w448","nodes":["n2733","n2734","n2735","n2736","n2737","n2738","n663","n664","n2739","n2733"],"tags":{"building":"yes"}},"w449":{"id":"w449","nodes":["n2564","n2565","n2566","n2567","n2568","n2794","n2795","n2564"],"tags":{"amenity":"parking"}},"w45":{"id":"w45","nodes":["n217","n218","n219","n220","n217"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w450":{"id":"w450","nodes":["n2799","n2728","n2729","n2730","n2731","n2732","n2799"],"tags":{"building":"yes"}},"w451":{"id":"w451","nodes":["n2441","n1170","n2442","n2575","n2443","n2445","n2444","n2448","n2441"],"tags":{"amenity":"parking"}},"w452":{"id":"w452","nodes":["n2273","n457","n2569","n458","n2570"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w453":{"id":"w453","nodes":["n2447","n2242","n2448","n2527","n2530"],"tags":{"highway":"service"}},"w454":{"id":"w454","nodes":["n2560","n333","n2561"],"tags":{"highway":"service","service":"parking_aisle"}},"w455":{"id":"w455","nodes":["n2679","n2680","n2681","n2682","n2683","n2684","n2685","n2686","n2687","n2688","n2689","n2690","n2679"],"tags":{"building":"yes"}},"w456":{"id":"w456","nodes":["n2425","n2429","n2424"],"tags":{"bridge":"yes","highway":"residential","name":"Moore Street"}},"w457":{"id":"w457","nodes":["n2487","n2467","n2472","n2480","n2495","n2487"],"tags":{"building":"yes"}},"w458":{"id":"w458","nodes":["n2659","n2660","n2661","n2662","n678","n677","n2663","n2664","n2665","n2666","n675","n676","n2659"],"tags":{"building":"yes"}},"w459":{"id":"w459","nodes":["n2600","n2598","n2599","n2601","n2605","n2602","n2600"],"tags":{"building":"yes"}},"w46":{"id":"w46","nodes":["n221","n222","n223","n224","n221"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w460":{"id":"w460","nodes":["n2468","n2464","n2455","n2457","n2461","n2468"],"tags":{"building":"yes"}},"w461":{"id":"w461","nodes":["n2478","n2473","n683","n682","n2463","n681","n2478"],"tags":{"building":"yes"}},"w462":{"id":"w462","nodes":["n2547","n473","n2548","n2549"],"tags":{"highway":"service","service":"parking_aisle"}},"w463":{"id":"w463","nodes":["n2573","n2574"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w464":{"id":"w464","nodes":["n2445","n2597","n2527","n2528","n2529","n2530","n2531","n2597"],"tags":{"highway":"service","service":"parking_aisle"}},"w465":{"id":"w465","nodes":["n2571","n459","n2572"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w466":{"id":"w466","nodes":["n2445","n2574","n2552","n442","n2551","n4727","n323","n2446"],"tags":{"highway":"service"}},"w467":{"id":"w467","nodes":["n2484","n2474","n2477","n2485","n2488","n2484"],"tags":{"building":"yes"}},"w468":{"id":"w468","nodes":["n2695","n2696","n2697","n2698","n2699","n2700","n2701","n2702","n2695"],"tags":{"building":"yes"}},"w469":{"id":"w469","nodes":["n2469","n2476","n2481","n2475","n920","n2466","n2469"],"tags":{"building":"yes"}},"w47":{"id":"w47","nodes":["n1988","n1997","n1989","n25","n24","n1990","n26","n1991","n21","n1992","n2006","n1993","n22","n1994","n23","n1995","n1999","n1996","n2001","n1988"],"tags":{"highway":"service"}},"w470":{"id":"w470","nodes":["n2473","n2470","n2465","n2458","n2462","n683","n2473"],"tags":{"building":"yes"}},"w471":{"id":"w471","nodes":["n2490","n2496","n994","n997","n998","n996","n995","n2485","n2477","n2490"],"tags":{"building":"yes"}},"w472":{"id":"w472","nodes":["n2424","n2426","n2427","n2428"],"tags":{"highway":"residential","name":"Moore Street"}},"w473":{"id":"w473","nodes":["n2432","n1026","n4741","n2554","n2425"],"tags":{"highway":"residential","name":"Moore Street"}},"w474":{"id":"w474","nodes":["n2577","n2576"],"tags":{"bridge":"yes","highway":"footway"}},"w475":{"id":"w475","nodes":["n2497","n2505","n2500","n2493","n2497"],"tags":{"building":"yes"}},"w476":{"id":"w476","nodes":["n2493","n2500","n2501","n2496","n2490","n2493"],"tags":{"building":"yes"}},"w477":{"id":"w477","nodes":["n2431","n360","n4726","n418","n397","n396","n2547","n646","n2447","n644","n2418","n424","n640","n2419","n2420","n2423"],"tags":{"highway":"residential","name":"Railroad Drive"}},"w478":{"id":"w478","nodes":["n2515","n2511","n2498","n2504","n2509","n2515"],"tags":{"building":"yes"}},"w479":{"id":"w479","nodes":["n2525","n651","n650","n2526","n2524","n653","n652","n656","n2523","n654","n2518","n2517","n2521","n2522","n2525"],"tags":{"building":"yes"}},"w48":{"id":"w48","nodes":["n225","n237","n226","n227","n228","n229","n230","n231","n232","n233","n234","n235","n236","n225"],"tags":{"building":"yes"}},"w480":{"id":"w480","nodes":["n2703","n2704","n2710","n2711","n2705","n2706","n2703"],"tags":{"amenity":"parking"}},"w481":{"id":"w481","nodes":["n2796","n2657","n2658","n2797","n2796"],"tags":{"building":"yes"}},"w482":{"id":"w482","nodes":["n2550","n2551","n442","n2552","n2553","n2550"],"tags":{"amenity":"parking"}},"w483":{"id":"w483","nodes":["n2790","n2542"],"tags":{"highway":"service","service":"parking_aisle"}},"w484":{"id":"w484","nodes":["n2311","n1102"],"tags":{"highway":"service"}},"w485":{"id":"w485","nodes":["n2515","n2509","n2516","n2519","n2515"],"tags":{"building":"yes"}},"w486":{"id":"w486","nodes":["n2506","n2502","n2492","n2491","n2494","n2506"],"tags":{"building":"yes"}},"w487":{"id":"w487","nodes":["n2667","n2668","n2669","n2670","n2667"],"tags":{"building":"yes"}},"w488":{"id":"w488","nodes":["n2616","n2608","n2617","n2618","n2619","n2620","n2621","n2622","n2623","n2624","n2625","n2626","n2627","n2628","n2616"],"tags":{"building":"yes"}},"w489":{"id":"w489","nodes":["n2081","n2430"],"tags":{"bridge":"yes","highway":"primary","name":"Michigan Avenue"}},"w49":{"id":"w49","nodes":["n237","n238"],"tags":{"highway":"footway"}},"w490":{"id":"w490","nodes":["n2410","n636","n730","n635","n2409","n2694","n2751","n2765","n2753","n2768","n2754","n2769","n2745","n2766","n4503","n2763","n4501","n2752","n2781"],"tags":{"highway":"residential","name":"Portage Avenue"}},"w491":{"id":"w491","nodes":["n2578","n2579","n2580","n2581","n2578"],"tags":{"amenity":"shelter","building":"yes","shelter_type":"picnic_shelter"}},"w492":{"id":"w492","nodes":["n2556","n2557","n2558","n2559","n2556"],"tags":{"amenity":"parking"}},"w493":{"id":"w493","nodes":["n2460","n2456","n687","n2453","n2454","n2460"],"tags":{"building":"yes"}},"w494":{"id":"w494","nodes":["n2471","n2479","n2476","n2469","n2471"],"tags":{"building":"yes"}},"w495":{"id":"w495","nodes":["n2724","n2725","n673","n672","n671","n2726","n2727"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w496":{"id":"w496","nodes":["n2649","n2650","n2651","n2652","n2653","n2654","n2655","n2656","n2649"],"tags":{"building":"yes"}},"w497":{"id":"w497","nodes":["n2430","n2446","n343","n2101","n2560","n2431","n363","n2748"],"tags":{"highway":"primary","name":"Michigan Avenue"}},"w498":{"id":"w498","nodes":["n2691","n2692","n634","n633","n2693","n2694"],"tags":{"highway":"service"}},"w499":{"id":"w499","nodes":["n2423","n2415","n661","n2416","n2417","n2719","n2721","n2772","n2756","n2773","n2759","n2767"],"tags":{"highway":"residential","name":"West Street"}},"w5":{"id":"w5","nodes":["n380","n381","n382","n383","n429","n430","n380"],"tags":{"building":"yes"}},"w50":{"id":"w50","nodes":["n239","n499","n508","n245","n238","n242","n240"],"tags":{"footway":"sidewalk","highway":"footway"}},"w500":{"id":"w500","nodes":["n2428","n1152","n2421","n2324"],"tags":{"bridge":"yes","highway":"residential","name":"Moore Street"}},"w501":{"id":"w501","nodes":["n2608","n2609","n2610","n2611","n2612","n2613","n2614","n2615","n2617","n2608"],"tags":{"building":"yes"}},"w502":{"id":"w502","nodes":["n2570","n2571"],"tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"}},"w503":{"id":"w503","nodes":["n2540","n2542","n2787"],"tags":{"highway":"service"}},"w504":{"id":"w504","nodes":["n2269","n2582","n2250"],"tags":{"highway":"path"}},"w505":{"id":"w505","nodes":["n2631","n2632","n2633","n2634","n2635","n2636","n2637","n2638","n2631"],"tags":{"building":"yes"}},"w506":{"id":"w506","nodes":["n2543","n2544","n2545","n395","n2546","n2543"],"tags":{"amenity":"parking"}},"w507":{"id":"w507","nodes":["n2449","n2450","n2451","n2452","n1162","n2449"],"tags":{"leisure":"pitch","sport":"tennis"}},"w508":{"id":"w508","nodes":["n2554","n1160","n2559","n2558","n659","n2555","n658","n657","n2419"],"tags":{"highway":"service"}},"w509":{"id":"w509","nodes":["n2499","n2508","n2510","n2505","n2497","n2499"],"tags":{"building":"yes"}},"w51":{"id":"w51","nodes":["n241","n242","n243","n244"],"tags":{"highway":"service","surface":"unpaved"}},"w510":{"id":"w510","nodes":["n2575","n2577"],"tags":{"highway":"footway"}},"w511":{"id":"w511","nodes":["n2533","n2534","n2535","n2536","n2537","n2538","n2539","n2785","n2786","n2533"],"tags":{"amenity":"parking"}},"w512":{"id":"w512","nodes":["n2801","n2740","n2741","n2742","n2743","n2744","n2801"],"tags":{"building":"yes"}},"w513":{"id":"w513","nodes":["n2720","n2721"],"tags":{"highway":"service","service":"parking_aisle"}},"w514":{"id":"w514","nodes":["n2788","n2790","n2789","n989","n2540","n2541"],"tags":{"highway":"service","service":"parking_aisle"}},"w515":{"id":"w515","nodes":["n2848","n2849","n2850","n2851","n2803","n2804","n2812"],"tags":{"highway":"residential","name":"Middle Street"}},"w516":{"id":"w516","nodes":["n2852","n2805"],"tags":{"access":"private","highway":"service","name":"Battle Street"}},"w517":{"id":"w517","nodes":["n2863","n2815","n2814","n2812","n2864","n2855","n2865","n2867","n2868"],"tags":{"highway":"secondary","name":"Michigan Avenue","name_1":"State Highway 60","ref":"M 60"}},"w518":{"id":"w518","nodes":["n2859","n2808"],"tags":{"highway":"residential","name":"2nd Avenue"}},"w519":{"id":"w519","nodes":["n2823","n2824","n2825","n2826","n2827","n2828","n2823"],"tags":{"building":"yes"}},"w52":{"id":"w52","nodes":["n247","n248","n249","n250","n247"],"tags":{"amenity":"parking"}},"w520":{"id":"w520","nodes":["n2806","n2807","n2803"],"tags":{"highway":"residential","name":"2nd Avenue"}},"w521":{"id":"w521","nodes":["n2829","n2830","n2831","n2832","n2833","n2834","n2835","n2836","n2837","n2838","n2829"],"tags":{"building":"yes"}},"w522":{"id":"w522","nodes":["n2815","n2813","n2811","n4597","n2846","n4596","n2857","n4601","n2853","n4602","n2861","n4","n2879","n4560","n3550","n5","n1685"],"tags":{"highway":"residential","name":"Washington Street"}},"w523":{"id":"w523","nodes":["n2878","n2811","n2810","n2860","n2880","n2881","n2882"],"tags":{"highway":"residential","name":"5th Avenue"}},"w524":{"id":"w524","nodes":["n2816","n2817","n2818","n2819","n2820","n2821","n2822","n2816"],"tags":{"building":"yes"}},"w525":{"id":"w525","nodes":["n2869","n2856","n2806","n2808","n2814","n2809","n2810","n2847","n2858","n2854","n2870","n2871","n6","n2872","n2839","n2862"],"tags":{"highway":"residential","name":"Wood Street"}},"w526":{"id":"w526","nodes":["n2877","n2809","n2813","n2844","n2843"],"tags":{"highway":"residential","name":"4th Avenue"}},"w527":{"id":"w527","nodes":["n4785","n4784","n2936","n4788","n4787","n4786","n4785"],"tags":{"amenity":"parking"}},"w528":{"id":"w528","nodes":["n2864","n2892","n2893","n2877","n2860","n3840"],"tags":{"highway":"residential","name":"Garden Street"}},"w529":{"id":"w529","nodes":["n2868","n2890"],"tags":{"bridge":"yes","highway":"secondary","name":"Michigan Avenue","name_1":"State Highway 60","ref":"M 60"}},"w53":{"id":"w53","nodes":["n251","n252","n253","n254","n255","n256","n257","n258","n259","n260","n261","n262","n251"],"tags":{"building":"yes"}},"w530":{"id":"w530","nodes":["n2914","n2915","n2916","n2917","n2918","n2919","n2920","n2921","n2922","n2923","n2924","n2925","n2926","n2927","n2928","n2929","n2930","n2931","n2932","n2933","n2914"],"tags":{"building":"yes"}},"w531":{"id":"w531","nodes":["n2958","n2896"],"tags":{"bridge":"yes","highway":"secondary","name":"Main Street"}},"w532":{"id":"w532","nodes":["n2896","n394","n364","n2748"],"tags":{"highway":"secondary","name":"Main Street"}},"w533":{"id":"w533","nodes":["n2800","n2943","n2940","n2941","n2942","n2943"],"tags":{"highway":"service","service":"parking_aisle"}},"w534":{"id":"w534","nodes":["n3836","n3837","n3839","n3838","n3834","n4632","n3831","n4624","n3835","n3836"],"tags":{"barrier":"fence"}},"w535":{"id":"w535","nodes":["n2894","n2944","n2774","n2765"],"tags":{"highway":"residential","name":"5th Avenue"}},"w536":{"id":"w536","nodes":["n2890","n2780","n627","n2889","n2887","n623","n2888","n366","n2748"],"tags":{"highway":"secondary","name":"Michigan Avenue","name_1":"State Highway 60","ref":"M 60"}},"w537":{"id":"w537","nodes":["n2895","n738","n2887","n737","n2913"],"tags":{"highway":"residential","name":"Water Street"}},"w538":{"id":"w538","nodes":["n2855","n3756","n2884","n2885","n2886","n2945","n2946","n2947","n2948","n2949","n2950","n2951","n2952","n2953","n2955","n2848","n2956","n2856"],"tags":{"highway":"residential","name":"River Drive"}},"w539":{"id":"w539","nodes":["n2882","n2894"],"tags":{"bridge":"yes","highway":"residential","name":"5th Avenue"}},"w54":{"id":"w54","nodes":["n263","n264","n265","n266","n267","n268","n269","n270","n271","n272","n273","n274","n275","n276","n263"],"tags":{"building":"yes"}},"w540":{"id":"w540","nodes":["n2987","n2964","n2981","n2983","n2966","n2982","n2962","n2960","n2967","n2965","n2984","n2977","n2968","n2976","n2986","n2988","n2963","n2970","n2969","n2979","n2974","n2980","n2959","n2973","n2985","n2961","n2975","n2971","n2972","n2978","n2898","n2907","n2912","n2909","n2911","n2901","n2903","n2904","n2906","n2902","n2900","n2910","n2908","n2899","n2897","n2905","n2186","n2233"],"tags":{"name":"Portage River","waterway":"river"}},"w541":{"id":"w541","nodes":["n2852","n2851","n3003"],"tags":{"highway":"residential","name":"1st Avenue"}},"w542":{"id":"w542","nodes":["n2991","n3004","n2994"],"tags":{"highway":"residential","name":"River Street"}},"w543":{"id":"w543","nodes":["n2993","n2989"],"tags":{"bridge":"yes","highway":"residential","name":"6th Street"}},"w544":{"id":"w544","nodes":["n2995","n2996","n2997","n2998","n2999","n3000","n3001","n3002","n2990","n2991","n2993"],"tags":{"highway":"residential","name":"6th Street"}},"w545":{"id":"w545","nodes":["n2989","n2992","n2848"],"tags":{"highway":"residential","name":"6th Street"}},"w546":{"id":"w546","nodes":["n2313","n3169","n3170","n3171","n3172","n3173","n3174","n3175","n3176","n3177","n3178","n3179","n3180","n3191","n3181","n3190","n3182","n3183","n3184","n3185","n3186","n3187","n3188","n3189","n3160","n3161","n3162","n2126","n2146","n2156","n2129","n2112","n2109","n2313"],"tags":{"natural":"wetland"}},"w547":{"id":"w547","nodes":["n2088","n3013","n3015","n3014","n3017","n3018"],"tags":{"name":"Conrail Railroad","railway":"rail"}},"w548":{"id":"w548","nodes":["n3083","n3084","n3085","n3086","n3083"],"tags":{"building":"yes"}},"w549":{"id":"w549","nodes":["n3020","n2288","n2283","n2284","n2131","n2286","n2287","n2285","n2132","n2140","n2289","n3020"],"tags":{"leisure":"park","name":"Conservation Park"}},"w55":{"id":"w55","nodes":["n277","n278","n279","n280","n281","n282","n283","n284","n277"],"tags":{"building":"yes"}},"w550":{"id":"w550","nodes":["n3056","n3042","n3041","n3040","n3039","n3038","n3037","n3036","n3044","n3035","n3034","n3043","n3016","n3056","n3019","n3015","n3012"],"tags":{"highway":"service"}},"w551":{"id":"w551","nodes":["n3044","n3045","n3046","n3047","n3048","n3049","n3050","n3051","n3052","n3053","n3054","n3055","n3016"],"tags":{"highway":"footway"}},"w552":{"id":"w552","nodes":["n3117","n3118","n3119","n3120","n3121","n3122","n3117"],"tags":{"building":"yes"}},"w553":{"id":"w553","nodes":["n3123","n3124","n3129","n3125","n3126","n3123"],"tags":{"building":"yes"}},"w554":{"id":"w554","nodes":["n3069","n3070","n3071","n3072","n3073","n3074","n3075","n3076","n3077","n3078","n3079","n3080","n3081","n3082","n3069"],"tags":{"building":"yes"}},"w555":{"id":"w555","nodes":["n3087","n3088","n3089","n3090","n3087"],"tags":{"building":"yes"}},"w556":{"id":"w556","nodes":["n3113","n3114","n3115","n3116","n3113"],"tags":{"building":"yes"}},"w557":{"id":"w557","nodes":["n3103","n3104","n3105","n3106","n3103"],"tags":{"building":"yes"}},"w558":{"id":"w558","nodes":["n3127","n3128","n3129","n3124","n3127"],"tags":{"building":"yes"}},"w559":{"id":"w559","nodes":["n3137","n3141","n3142","n3138","n3139","n3140","n3137"],"tags":{"building":"yes"}},"w56":{"id":"w56","nodes":["n285","n286","n287","n288","n285"],"tags":{"amenity":"parking"}},"w560":{"id":"w560","nodes":["n3091","n3092","n3093","n3094","n3091"],"tags":{"building":"yes"}},"w561":{"id":"w561","nodes":["n3155","n3157","n3158","n3159","n3156","n3155"],"tags":{"building":"yes"}},"w562":{"id":"w562","nodes":["n3057","n3058","n3059","n3060","n3057"],"tags":{"building":"yes"}},"w563":{"id":"w563","nodes":["n3107","n3108","n3109","n3110","n3111","n3112","n3107"],"tags":{"building":"yes"}},"w564":{"id":"w564","nodes":["n3134","n3135","n3136","n3131","n3134"],"tags":{"building":"yes"}},"w565":{"id":"w565","nodes":["n3143","n3144","n3145","n3146","n3143"],"tags":{"building":"yes"}},"w566":{"id":"w566","nodes":["n3095","n3096","n3097","n3098","n3095"],"tags":{"building":"yes"}},"w567":{"id":"w567","nodes":["n3130","n3131","n3136","n3132","n3133","n3130"],"tags":{"building":"yes"}},"w568":{"id":"w568","nodes":["n3025","n3026","n3027","n3028","n3029","n3030","n3031","n3033","n3032","n3025"],"tags":{"amenity":"parking"}},"w569":{"id":"w569","nodes":["n3061","n3062","n3063","n3064","n3061"],"tags":{"building":"yes"}},"w57":{"id":"w57","nodes":["n289","n290","n291","n292","n289"],"tags":{"amenity":"parking"}},"w570":{"id":"w570","nodes":["n3155","n3156","n3152","n3153","n3155"],"tags":{"building":"yes"}},"w571":{"id":"w571","nodes":["n3099","n3100","n3101","n3102","n3099"],"tags":{"building":"yes"}},"w572":{"id":"w572","nodes":["n3147","n3148","n3149","n3150","n3147"],"tags":{"building":"yes"}},"w573":{"id":"w573","nodes":["n3039","n2284"],"tags":{"highway":"service"}},"w574":{"id":"w574","nodes":["n3151","n3152","n3153","n3154","n3151"],"tags":{"building":"yes"}},"w575":{"id":"w575","nodes":["n3021","n3022","n3023","n3024","n3021"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w576":{"id":"w576","nodes":["n3065","n3066","n3067","n3068","n3065"],"tags":{"building":"yes"}},"w577":{"id":"w577","nodes":["n2944","n3192","n3757","n3813","n3814","n3815","n3816","n3817","n3818","n3819"],"tags":{"highway":"service","name":"Willow Drive","service":"driveway","surface":"unpaved"}},"w578":{"id":"w578","nodes":["n2163","n2165","n2166","n2167","n2168","n2172","n2173","n2174","n2175","n2176","n2178","n2181","n2163"],"tags":{"building":"yes"}},"w579":{"id":"w579","nodes":["n2754","n3195","n3204","n3205","n4537","n4540","n3206","n4530","n4536","n3207","n4524","n3199","n4521","n3197","n1032"],"tags":{"highway":"residential","name":"Elm Street"}},"w58":{"id":"w58","nodes":["n240","n293","n294"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w580":{"id":"w580","nodes":["n2184","n2185","n2187","n2190","n2191","n2192","n2184"],"tags":{"building":"yes"}},"w581":{"id":"w581","nodes":["n2765","n3208","n3211","n2755","n3280","n2756","n3346"],"tags":{"highway":"residential","name":"Kelsey Street"}},"w582":{"id":"w582","nodes":["n2753","n3194","n3193","n3201","n3196","n4551","n3202","n4550","n3203","n3200","n3198","n1033"],"tags":{"highway":"residential","name":"Walnut Street"}},"w583":{"id":"w583","nodes":["n3272","n4469","n4588","n2879","n4564","n2872"],"tags":{"highway":"residential","name":"10th Avenue"}},"w584":{"id":"w584","nodes":["n3243","n3242","n3241","n3240","n3243"],"tags":{"building":"industrial"}},"w585":{"id":"w585","nodes":["n3273","n3274","n4631","n4593","n3275","n4592","n2846","n4611","n2847"],"tags":{"highway":"residential","name":"6th Avenue"}},"w586":{"id":"w586","nodes":["n3276","n4591","n2853","n4605","n2854"],"tags":{"highway":"residential","name":"8th Avenue"}},"w587":{"id":"w587","nodes":["n3269","n3268","n3267","n3266","n3265","n3264","n3263","n3262","n3269"],"tags":{"building":"industrial"}},"w588":{"id":"w588","nodes":["n3277","n4599","n2857","n4598","n4608","n2858"],"tags":{"highway":"residential","name":"7th Avenue"}},"w589":{"id":"w589","nodes":["n3239","n3238","n3271","n3270","n3237","n3236","n3235","n3234","n3239"],"tags":{"building":"yes"}},"w59":{"id":"w59","nodes":["n294","n295","n296","n297","n298","n299","n300","n301","n302","n303","n491","n304","n305","n306","n307"],"tags":{"footway":"sidewalk","highway":"footway"}},"w590":{"id":"w590","nodes":["n3278","n4458","n4589","n4604","n2861"],"tags":{"highway":"residential","name":"9th Avenue"}},"w591":{"id":"w591","nodes":["n3253","n3252","n3251","n3250","n3249","n3248","n3253"],"tags":{"building":"industrial"}},"w592":{"id":"w592","nodes":["n3229","n3228","n3227","n3226","n3225","n3224","n3223","n3222","n3221","n3220","n3219","n3218","n3217","n3216","n3215","n3214","n3213","n3212","n3229"],"tags":{"natural":"water","water":"pond"}},"w593":{"id":"w593","nodes":["n3261","n3260","n3259","n3258","n3257","n3256","n3255","n3254","n3261"],"tags":{"building":"industrial"}},"w594":{"id":"w594","nodes":["n3233","n3232","n3231","n3230","n3233"],"tags":{"building":"yes"}},"w595":{"id":"w595","nodes":["n3247","n3246","n3245","n3244","n3247"],"tags":{"building":"industrial"}},"w596":{"id":"w596","nodes":["n2769","n3195","n3193","n3209","n2758","n2759","n3279"],"tags":{"highway":"residential","name":"Armitage Street"}},"w597":{"id":"w597","nodes":["n2193","n2194","n2195","n2197","n2193"],"tags":{"building":"yes"}},"w598":{"id":"w598","nodes":["n3404","n3403","n3402","n3401","n3400","n3399","n3398","n3397","n3373","n3372","n3396","n3395","n3404"],"tags":{"building":"school"}},"w6":{"id":"w6","nodes":["n879","n880","n881","n882","n879"],"tags":{"building":"shed"}},"w60":{"id":"w60","nodes":["n239","n308","n307"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w600":{"id":"w600","nodes":["n3387","n3386","n3316","n3315","n3314","n3313","n3387"],"tags":{"building":"yes"}},"w601":{"id":"w601","nodes":["n3304","n3303","n3302","n3301","n3385","n3384","n3300","n3299","n3304"],"tags":{"building":"yes"}},"w602":{"id":"w602","nodes":["n3334","n3333","n3332","n3331","n3330","n3329","n3328","n3327","n3326","n3325","n3324","n3323","n3322","n3321","n3320","n3319","n3318","n3317","n3334"],"tags":{"building":"yes"}},"w603":{"id":"w603","nodes":["n3353","n3352","n3347","n3280","n2798"],"tags":{"highway":"service","service":"alley","surface":"unpaved"}},"w604":{"id":"w604","nodes":["n3753","n3211","n3383"],"tags":{"highway":"service","service":"alley"}},"w605":{"id":"w605","nodes":["n3290","n3289","n3288","n3287","n3286","n3285","n3284","n3283","n3282","n3281","n3290"],"tags":{"building":"yes"}},"w606":{"id":"w606","nodes":["n2198","n2199","n2201","n2202","n2203","n2206","n2198"],"tags":{"building":"yes"}},"w607":{"id":"w607","nodes":["n2198","n2207"],"tags":{"barrier":"wall"}},"w608":{"id":"w608","nodes":["n2751","n3208","n3210","n3209","n3415","n3410","n3414","n3413","n3412","n3416"],"tags":{"highway":"residential","name":"East Street"}},"w609":{"id":"w609","nodes":["n2772","n3346","n3746","n3748","n3747","n3345","n3378","n3279","n3411"],"tags":{"highway":"residential","name":"Maple Street"}},"w61":{"id":"w61","nodes":["n309","n310","n311","n312","n313","n240"],"tags":{"footway":"sidewalk","highway":"footway"}},"w610":{"id":"w610","nodes":["n3379","n3380","n3382","n3381","n3379"],"tags":{"leisure":"park","name":"LaFayette Park"}},"w611":{"id":"w611","nodes":["n2768","n3194","n3210","n3753","n2760","n3353","n2773","n3378"],"tags":{"highway":"residential","name":"Bennett Street"}},"w612":{"id":"w612","nodes":["n2751","n3383","n2749","n2798","n2772"],"tags":{"highway":"residential","name":"Market Street"}},"w613":{"id":"w613","nodes":["n3298","n3297","n3296","n3295","n3294","n3293","n3292","n3291","n3298"],"tags":{"building":"yes"}},"w614":{"id":"w614","nodes":["n3375","n3406","n3405","n3374","n3375"],"tags":{"leisure":"playground"}},"w615":{"id":"w615","nodes":["n3393","n3344","n3343","n3342","n3341","n3340","n3339","n3338","n3337","n3392","n3391","n3390","n3389","n3336","n3335","n3388","n3393"],"tags":{"building":"yes"}},"w616":{"id":"w616","nodes":["n3376","n3407","n3408","n3377","n3376"],"tags":{"amenity":"school","name":"Three Rivers Elementary School"}},"w617":{"id":"w617","nodes":["n3312","n3311","n3310","n3309","n3308","n3307","n3306","n3305","n3312"],"tags":{"building":"yes"}},"w619":{"id":"w619","nodes":["n2863","n3424","n3425","n3426","n3427","n3428","n3429","n3430","n3431","n3432","n3433","n2844"],"tags":{"highway":"secondary","name":"Michigan Avenue","ref":"M 60"}},"w62":{"id":"w62","nodes":["n876","n906","n904","n875","n874","n873","n872","n871","n870","n869","n41","n868","n146","n314","n315","n1956"],"tags":{"footway":"sidewalk","highway":"footway"}},"w620":{"id":"w620","nodes":["n2844","n3420","n3421","n3422","n3439","n2859","n3437","n3493","n3496","n3500","n3497"],"tags":{"highway":"residential"}},"w621":{"id":"w621","nodes":["n3468","n3469","n3470","n3471","n3468"],"tags":{"building":"yes"}},"w622":{"id":"w622","nodes":["n3417","n3436","n3438","n3491","n3488","n3492","n3495","n3494","n3498","n3487","n3499","n3490","n3489","n4800","n3417"],"tags":{"landuse":"cemetery","name":"Riverside Cemetery"}},"w623":{"id":"w623","nodes":["n3440","n3441","n3442","n3443","n3444","n3445","n3440"],"tags":{"building":"yes"}},"w624":{"id":"w624","nodes":["n3446","n3447","n3448","n3449","n3450","n3451","n3452","n3453","n3454","n3455","n3456","n3457","n3458","n3459","n3460","n3461","n3462","n3463","n3464","n3465","n3466","n3467","n3446"],"tags":{"building":"yes"}},"w625":{"id":"w625","nodes":["n2844","n3434","n3435","n2878","n3275","n4621","n3276","n3278","n4463","n3272","n3472","n3474","n3475","n3476","n3477","n3478","n1202","n3479","n3480","n3481","n1203","n3482","n3483","n3484","n3485","n4574","n3486","n3473"],"tags":{"highway":"secondary","name":"Jefferson Street","name_1":"State Highway 60","ref":"M 60"}},"w626":{"id":"w626","nodes":["n3439","n3423","n2863"],"tags":{"highway":"unclassified","name":"Michigan Avenue","name_1":"State Highway 60"}},"w627":{"id":"w627","nodes":["n3500","n3005"],"tags":{"highway":"service"}},"w628":{"id":"w628","nodes":["n3491","n3488","n3492","n3010","n3009","n3005","n3008","n3007","n3006","n3502","n3491"],"tags":{"leisure":"park","name":"Marina Park"}},"w629":{"id":"w629","nodes":["n2208","n2209","n2212","n2214","n2208"],"tags":{"building":"yes"}},"w63":{"id":"w63","nodes":["n1955","n316"],"tags":{"footway":"sidewalk","highway":"footway"}},"w630":{"id":"w630","nodes":["n2757","n3414","n3202","n4542","n3206","n4538","n3750","n3503","n1629","n4500","n2763","n4502","n2764","n3508"],"tags":{"highway":"residential","name":"Hoffman Street"}},"w631":{"id":"w631","nodes":["n2215","n2750","n2770","n2771","n2215"],"tags":{"building":"yes"}},"w632":{"id":"w632","nodes":["n2766","n3504","n3507","n3751","n3205","n3196","n3410","n2746"],"tags":{"highway":"residential","name":"Cushman Street"}},"w633":{"id":"w633","nodes":["n2745","n3749","n3507","n4535","n3503"],"tags":{"highway":"residential","name":"Pine Street"}},"w634":{"id":"w634","nodes":["n3510","n3511","n3512","n3509","n3510"],"tags":{"leisure":"park","name":"Bowman Park"}},"w636":{"id":"w636","nodes":["n2745","n3752","n3204","n3201","n3415","n2761","n2767","n3411"],"tags":{"highway":"residential","name":"Wheeler Street"}},"w637":{"id":"w637","nodes":["n3550","n4586","n4476","n3472"],"tags":{"highway":"residential","name":"11th Avenue"}},"w638":{"id":"w638","nodes":["n3508","n3518"],"tags":{"bridge":"yes","highway":"residential","name":"Hoffman Street"}},"w639":{"id":"w639","nodes":["n3518","n1204","n2862","n3519","n3520","n3521","n3522","n3523","n2161","n3524","n3549","n3552","n4239","n3551","n4577","n4582","n4578","n4583","n4579","n4574"],"tags":{"highway":"residential","name":"Hoffman Street"}},"w64":{"id":"w64","nodes":["n316","n317"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w640":{"id":"w640","nodes":["n3634","n3640","n3676","n3633","n3678","n3648","n3638","n3683","n3600","n3579","n3679","n3677","n2987","n3592","n3588","n3608","n3559","n3617","n3620","n3660","n3553","n3533","n3530","n3531","n3525","n3527","n3526","n3532","n3529","n3528","n3667","n3627","n3623","n3625","n3601","n3687","n3671","n3644","n3626","n3673","n3582","n3693","n3605","n3619","n3651","n3650","n3615","n3663","n3631","n3596","n3604","n3655","n3586","n3595","n3701","n3603","n3686","n3611","n3568","n3674","n3613","n3580","n3562","n3564","n3689","n3585","n3670","n3659","n3684","n3680","n3646","n3558","n3556","n3692","n3563","n3575","n3571","n3675","n3557","n3700","n3656","n3622","n3657","n3565","n3669","n3658","n3618","n3624","n3688","n3610","n3570","n3645","n3649","n3583","n3694","n3561","n3554","n3614","n3698","n3581","n3635","n3641","n3569","n3647","n3628","n3598","n3696","n3665","n3639","n3607","n3695","n3642","n3672","n3577","n3643","n3691","n3602","n3576","n3591","n3560","n3606","n3685","n3597","n3629","n3661","n3654","n3616","n3697","n3578","n3609","n3653","n3699","n3566","n3637","n3567","n3666","n3555","n3599","n3590","n3572","n3593","n3690","n3681","n3612","n3682","n3668","n3587","n3621","n3636","n3662","n3589","n3573","n3652","n3664","n3632","n3574","n3594","n3584","n3630","n3634"],"tags":{"landuse":"reservoir","name":"Hoffman Pond","natural":"water"}},"w641":{"id":"w641","nodes":["n2988","n3534","n3535","n3536","n3537","n3538","n3539","n3540","n3541","n3542","n3543","n3544","n3545","n3546","n3547","n3548","n2970"],"tags":{"waterway":"river"}},"w642":{"id":"w642","nodes":["n3702","n3703","n3704","n3705","n3706","n3707","n3708","n3709","n3710","n3711","n3712","n3713","n3714","n3715","n3716","n3717","n3718","n3719","n3720","n3721","n3722","n3723","n3724","n3725","n3726","n3727","n3728","n3729","n3730","n3731","n3732","n3733","n3734","n3735","n3736","n3737","n3738","n3739","n3740","n3741","n3742","n3743","n3702"],"tags":{"admin_level":"8","boundary":"administrative"}},"w643":{"id":"w643","nodes":["n2839","n2873"],"tags":{"highway":"service","service":"driveway"}},"w644":{"id":"w644","nodes":["n2873","n2840"],"tags":{"bridge":"yes","highway":"service","layer":"1","service":"driveway"}},"w645":{"id":"w645","nodes":["n2840","n2841","n2842","n2845","n2866"],"tags":{"highway":"service","service":"driveway","surface":"unpaved"}},"w646":{"id":"w646","nodes":["n2752","n3759","n1420","n1421","n1422","n3758","n4507","n4506","n4505","n4520","n3199","n4522","n4504","n4546","n3200","n4547","n3412"],"tags":{"highway":"residential","name":"Flower Street"}},"w647":{"id":"w647","nodes":["n2874","n2875","n2876","n2954","n2874"],"tags":{"building":"industrial"}},"w648":{"id":"w648","nodes":["n3778","n3779","n3780","n3781","n3782","n3783","n3778"],"tags":{"building":"yes"}},"w649":{"id":"w649","nodes":["n3197","n4543","n4544","n3198"],"tags":{"highway":"residential","name":"Morris Avenue","surface":"unpaved"}},"w65":{"id":"w65","nodes":["n317","n318","n319","n320","n321"],"tags":{"footway":"sidewalk","highway":"footway"}},"w650":{"id":"w650","nodes":["n3207","n4526","n4528","n4548","n3203","n4549","n3413","n2762"],"tags":{"highway":"residential","name":"Adams Street"}},"w651":{"id":"w651","nodes":["n3788","n3785","n3786","n3787","n3788"],"tags":{"power":"station"}},"w652":{"id":"w652","nodes":["n2957","n3163","n3241"],"tags":{"barrier":"wall"}},"w653":{"id":"w653","nodes":["n3549","n3802","n3803","n3800","n3801"],"tags":{"highway":"service","surface":"unpaved"}},"w654":{"id":"w654","nodes":["n3164","n3165","n3166","n3167","n3168","n3505","n3164"],"tags":{"building":"yes"}},"w655":{"id":"w655","nodes":["n3506","n3517","n3760","n3761","n3762","n3763","n3506"],"tags":{"building":"yes"}},"w656":{"id":"w656","nodes":["n3764","n3765","n3766","n3767","n3768","n3769","n3770","n3771","n3764"],"tags":{"building":"yes"}},"w657":{"id":"w657","nodes":["n3772","n3773","n3774","n3775","n3772"],"tags":{"building":"yes"}},"w658":{"id":"w658","nodes":["n3776","n3777","n3784","n3789","n3776"],"tags":{"building":"yes"}},"w659":{"id":"w659","nodes":["n3930","n3931","n3932","n3933","n3934","n3935","n3936","n3937","n3938","n3930"],"tags":{"leisure":"pitch","sport":"baseball"}},"w66":{"id":"w66","nodes":["n321","n322"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w660":{"id":"w660","nodes":["n3982","n3842","n3864","n3865","n3866","n3867","n3868","n3858","n3869","n3870","n3862"],"tags":{"highway":"service"}},"w661":{"id":"w661","nodes":["n3968","n3969"],"tags":{"highway":"footway"}},"w662":{"id":"w662","nodes":["n3875","n3876","n3877","n3878","n3879","n3880","n3881","n3882","n3875"],"tags":{"amenity":"parking"}},"w663":{"id":"w663","nodes":["n3964","n3965"],"tags":{"highway":"footway"}},"w664":{"id":"w664","nodes":["n3966","n3967"],"tags":{"highway":"footway"}},"w665":{"id":"w665","nodes":["n3857","n3890","n3884","n3894","n3889","n3899","n3885","n3886","n3896","n3887"],"tags":{"highway":"service","service":"parking_aisle"}},"w666":{"id":"w666","nodes":["n3895","n3896"],"tags":{"highway":"service","service":"parking_aisle"}},"w667":{"id":"w667","nodes":["n3274","n3977","n3984","n3983","n3981","n3844","n3978","n3982","n3861","n3862","n3873","n3874","n4468","n3863"],"tags":{"access":"private","highway":"service","name":"Collins Drive"}},"w668":{"id":"w668","nodes":["n3900","n3901","n3902","n3903","n3904","n3905","n3808","n3809","n3906","n3907","n3908","n3967","n3909","n3910","n3911","n3955","n3964","n3912","n3913","n3914","n3915","n3916","n3917","n3918","n3919","n3920","n3921","n3922","n3923","n3924","n3925","n3926","n3927","n3969","n3970","n3928","n3807","n3929","n3900"],"tags":{"building":"school"}},"w669":{"id":"w669","nodes":["n3272","n39","n40","n3974","n3863","n3857","n3892","n3883","n3891","n3889"],"tags":{"highway":"service"}},"w67":{"id":"w67","nodes":["n322","n886","n323","n475"],"tags":{"footway":"crossing","highway":"footway"}},"w670":{"id":"w670","nodes":["n3473","n3859","n3860","n3980","n4908","n4865"],"tags":{"highway":"secondary","name":"Hoffman Street","ref":"M 60"}},"w671":{"id":"w671","nodes":["n3970","n3806","n3971"],"tags":{"highway":"footway"}},"w672":{"id":"w672","nodes":["n3892","n3893","n3894"],"tags":{"highway":"service","service":"parking_aisle"}},"w673":{"id":"w673","nodes":["n3945","n3946","n3992","n3990","n3945"],"tags":{"leisure":"pitch","sport":"tennis"}},"w674":{"id":"w674","nodes":["n3890","n3893","n3891"],"tags":{"highway":"service","service":"parking_aisle"}},"w675":{"id":"w675","nodes":["n3947","n3948","n3994","n3993","n3947"],"tags":{"leisure":"pitch","sport":"tennis"}},"w676":{"id":"w676","nodes":["n3858","n3954","n3972","n3810","n3811","n3812","n3841","n3973","n3898","n3963","n3897","n3896"],"tags":{"highway":"service"}},"w677":{"id":"w677","nodes":["n3977","n3996","n3997","n4004","n3998","n3999","n4005","n4007","n4006","n3995","n4000","n3843","n4001","n4002","n4003","n3949","n3950","n3951","n3952","n3953","n3954","n3956","n3966","n3955"],"tags":{"highway":"footway"}},"w678":{"id":"w678","nodes":["n3887","n3888","n3895","n3899"],"tags":{"highway":"service","service":"parking_aisle"}},"w679":{"id":"w679","nodes":["n3946","n3947","n3993","n3992","n3946"],"tags":{"leisure":"pitch","sport":"tennis"}},"w68":{"id":"w68","nodes":["n294","n1952","n326"],"tags":{"footway":"sidewalk","highway":"footway"}},"w680":{"id":"w680","nodes":["n3939","n3940","n3941","n3985","n3986","n3987","n3988","n3989","n3942","n3943","n3939"],"tags":{"leisure":"pitch","sport":"baseball"}},"w681":{"id":"w681","nodes":["n3990","n3991","n3944","n3945","n3990"],"tags":{"leisure":"pitch","sport":"tennis"}},"w682":{"id":"w682","nodes":["n3871","n3872","n3873","n3874","n3871"],"tags":{"amenity":"parking"}},"w683":{"id":"w683","nodes":["n3956","n3965","n3957","n3958","n3959"],"tags":{"footway":"sidewalk","highway":"footway"}},"w684":{"id":"w684","nodes":["n3790","n3791","n3792","n3793","n3790"],"tags":{"building":"shed"}},"w685":{"id":"w685","nodes":["n3794","n3795","n3796","n3797","n3794"],"tags":{"building":"yes"}},"w686":{"id":"w686","nodes":["n3798","n3799","n3804","n3805","n3798"],"tags":{"building":"yes"}},"w687":{"id":"w687","nodes":["n3806","n3807"],"tags":{"highway":"footway"}},"w688":{"id":"w688","nodes":["n3845","n3846","n3847","n3848","n3845"],"tags":{"leisure":"pitch","sport":"american_football"}},"w689":{"id":"w689","nodes":["n3849","n4021","n3850","n3851","n3852","n3853","n3854","n3855","n3856","n3975","n3976","n3979","n4008","n4009","n4010","n4011","n4012","n4013","n4014","n4015","n4016","n4017","n4018","n4019","n4020","n4021"],"tags":{"leisure":"track","sport":"running"}},"w69":{"id":"w69","nodes":["n326","n327"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w690":{"id":"w690","nodes":["n4022","n4023","n4024","n4025","n4026","n4027","n4022"],"tags":{"building":"yes"}},"w691":{"id":"w691","nodes":["n4028","n4029","n4030","n4031","n4028"],"tags":{"building":"yes"}},"w692":{"id":"w692","nodes":["n4032","n4033","n4034","n4035","n4032"],"tags":{"building":"yes"}},"w693":{"id":"w693","nodes":["n4036","n4037","n4038","n4039","n4036"],"tags":{"building":"yes"}},"w694":{"id":"w694","nodes":["n4040","n4041","n4042","n4043","n4040"],"tags":{"building":"yes"}},"w695":{"id":"w695","nodes":["n4044","n4045","n4050","n4053","n4046","n4047","n4048","n4049","n4044"],"tags":{"building":"yes"}},"w696":{"id":"w696","nodes":["n4050","n4051","n4052","n4053","n4050"],"tags":{"building":"roof"}},"w697":{"id":"w697","nodes":["n4054","n4068","n4055","n4056","n4057","n4054"],"tags":{"building":"yes"}},"w698":{"id":"w698","nodes":["n4058","n4059","n4060","n4061","n4062","n4063","n4058"],"tags":{"building":"yes"}},"w699":{"id":"w699","nodes":["n4064","n4066","n4065"],"tags":{"barrier":"fence"}},"w7":{"id":"w7","nodes":["n43","n44","n45"],"tags":{"highway":"service"}},"w70":{"id":"w70","nodes":["n327","n328","n27","n329"],"tags":{"footway":"sidewalk","highway":"footway"}},"w700":{"id":"w700","nodes":["n4066","n4067","n4068"],"tags":{"barrier":"fence"}},"w701":{"id":"w701","nodes":["n4069","n4070","n4071","n4072","n4069"],"tags":{"building":"shed"}},"w702":{"id":"w702","nodes":["n4073","n4074","n4075","n4076","n4077","n4078","n4079","n4080","n4081","n4082","n4083","n4084","n4073"],"tags":{"building":"yes"}},"w703":{"id":"w703","nodes":["n4085","n4093","n4086","n4087","n4088","n4089","n4090","n4091","n4092","n4085"],"tags":{"building":"yes"}},"w704":{"id":"w704","nodes":["n4093","n4094","n4095","n4096"],"tags":{"barrier":"fence"}},"w705":{"id":"w705","nodes":["n4097","n4098","n4099","n4100","n4097"],"tags":{"building":"yes"}},"w706":{"id":"w706","nodes":["n4098","n4102","n4087"],"tags":{"barrier":"fence"}},"w707":{"id":"w707","nodes":["n4101","n4102","n4096","n4170","n4103"],"tags":{"barrier":"fence"}},"w708":{"id":"w708","nodes":["n4104","n4105","n4106","n4107","n4104"],"tags":{"access":"private","leisure":"swimming_pool"}},"w709":{"id":"w709","nodes":["n4108","n4109","n4110","n4111","n4108"],"tags":{"building":"yes"}},"w71":{"id":"w71","nodes":["n329","n331"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w710":{"id":"w710","nodes":["n4112","n4113","n4114","n4115","n4116","n4117","n4118","n4119","n4112"],"tags":{"building":"yes"}},"w711":{"id":"w711","nodes":["n4120","n4121","n4122","n4123","n4120"],"tags":{"building":"yes"}},"w712":{"id":"w712","nodes":["n4124","n4125","n4126","n4127","n4128","n4129","n4124"],"tags":{"building":"yes"}},"w713":{"id":"w713","nodes":["n4130","n4131","n4132","n4133","n4130"],"tags":{"building":"shed"}},"w714":{"id":"w714","nodes":["n4134","n4135","n4136","n4137","n4138","n4139","n4140","n4141","n4142","n4143","n4134"],"tags":{"building":"yes"}},"w715":{"id":"w715","nodes":["n4144","n4145","n4146","n4147","n4148","n4149","n4144"],"tags":{"building":"yes"}},"w716":{"id":"w716","nodes":["n4150","n4151","n4152","n4153","n4150"],"tags":{"building":"yes"}},"w717":{"id":"w717","nodes":["n4154","n4155","n4156","n4157","n4154"],"tags":{"building":"yes"}},"w718":{"id":"w718","nodes":["n4158","n4159","n4160","n4161","n4162","n4163","n4164","n4165","n4158"],"tags":{"building":"yes"}},"w719":{"id":"w719","nodes":["n4166","n4167","n4168","n4169","n4166"],"tags":{"building":"yes"}},"w72":{"id":"w72","nodes":["n331","n344","n332","n333","n334"],"tags":{"footway":"sidewalk","highway":"footway"}},"w720":{"id":"w720","nodes":["n4170","n4171"],"tags":{"barrier":"fence"}},"w721":{"id":"w721","nodes":["n4138","n4103"],"tags":{"barrier":"fence"}},"w722":{"id":"w722","nodes":["n4103","n4172"],"tags":{"barrier":"fence"}},"w723":{"id":"w723","nodes":["n4173","n4174"],"tags":{"barrier":"fence"}},"w724":{"id":"w724","nodes":["n4175","n4176","n4177","n4178","n4175"],"tags":{"building":"yes"}},"w725":{"id":"w725","nodes":["n4179","n4180","n4181","n4182","n4183","n4184","n4179"],"tags":{"building":"yes"}},"w726":{"id":"w726","nodes":["n4185","n4186","n4187","n4188","n4185"],"tags":{"building":"yes"}},"w727":{"id":"w727","nodes":["n4189","n4190","n4191","n4192","n4193","n4194","n4195","n4196","n4197","n4198","n4199","n4200","n4201","n4202","n4189"],"tags":{"building":"yes"}},"w728":{"id":"w728","nodes":["n4203","n4204","n4205","n4206","n4207","n4208","n4209","n4210","n4203"],"tags":{"building":"yes"}},"w729":{"id":"w729","nodes":["n4211","n4212","n4213","n4214","n4211"],"tags":{"building":"shed"}},"w73":{"id":"w73","nodes":["n335","n336","n337","n338","n339","n340","n341","n342","n335"],"tags":{"building":"yes"}},"w730":{"id":"w730","nodes":["n4215","n4216","n4217","n4218","n4215"],"tags":{"building":"yes"}},"w731":{"id":"w731","nodes":["n4219","n4220","n4221","n4222","n4223","n4224","n4225","n4226","n4227","n4228","n4229","n4230","n4219"],"tags":{"building":"yes"}},"w732":{"id":"w732","nodes":["n4231","n4232","n4233","n4234","n4235","n4236","n4237","n4238","n4231"],"tags":{"building":"yes"}},"w733":{"id":"w733","nodes":["n4239","n4240","n4241","n4242","n4243","n4244","n4245","n4246","n4247","n4248","n4241"],"tags":{"highway":"service"}},"w734":{"id":"w734","nodes":["n4240","n4249","n4248"],"tags":{"highway":"service","service":"parking_aisle"}},"w735":{"id":"w735","nodes":["n4250","n4251","n4252","n4253","n4254","n4255","n4256","n4257","n4258","n4250"],"tags":{"amenity":"parking"}},"w736":{"id":"w736","nodes":["n4259","n4260","n4261","n4262","n4259"],"tags":{"building":"yes"}},"w737":{"id":"w737","nodes":["n4263","n4264","n4265","n4266","n4267","n4268","n4269","n4270","n4271","n4272","n4273","n4274","n4275","n4276","n4263"],"tags":{"building":"yes"}},"w738":{"id":"w738","nodes":["n4277","n4278","n4279","n4280","n4281","n4282","n4277"],"tags":{"building":"yes"}},"w739":{"id":"w739","nodes":["n4283","n4284","n4285","n4286","n4287","n4288","n4289","n4290","n4291","n4292","n4293","n4294","n4283"],"tags":{"building":"yes"}},"w74":{"id":"w74","nodes":["n343","n344","n345"],"tags":{"highway":"service"}},"w740":{"id":"w740","nodes":["n4295","n4296","n4297","n4298","n4295"],"tags":{"building":"yes"}},"w741":{"id":"w741","nodes":["n4299","n4300","n4301","n4302","n4303","n4304","n4305","n4306","n4307","n4308","n4309","n4310","n4299"],"tags":{"building":"yes"}},"w742":{"id":"w742","nodes":["n4311","n4312","n4313","n4314","n4311"],"tags":{"building":"shed"}},"w743":{"id":"w743","nodes":["n4315","n4316","n4317","n4318","n4319","n4320","n4315"],"tags":{"building":"yes"}},"w744":{"id":"w744","nodes":["n4321","n4322","n4323","n4324","n4325","n4326","n4327","n4328","n4329","n4330","n4331","n4332","n4333","n4334","n4321"],"tags":{"building":"yes"}},"w745":{"id":"w745","nodes":["n4335","n4336","n4337","n4338","n4335"],"tags":{"building":"shed"}},"w746":{"id":"w746","nodes":["n4339","n4340","n4341","n4342","n4343","n4344","n4339"],"tags":{"building":"yes"}},"w747":{"id":"w747","nodes":["n4345","n4346","n4347","n4348","n4345"],"tags":{"building":"yes"}},"w748":{"id":"w748","nodes":["n4349","n4350","n4351","n4352","n4349"],"tags":{"building":"yes"}},"w749":{"id":"w749","nodes":["n4353","n4354","n4355","n4356","n4357","n4358","n4353"],"tags":{"building":"yes"}},"w75":{"id":"w75","nodes":["n346","n347","n348","n349","n350","n351","n346"],"tags":{"amenity":"parking"}},"w750":{"id":"w750","nodes":["n4612","n4359","n4360"],"tags":{"barrier":"fence"}},"w751":{"id":"w751","nodes":["n4361","n4362","n4363","n4364","n4361"],"tags":{"building":"yes"}},"w752":{"id":"w752","nodes":["n4365","n4366","n4367","n4368","n4365"],"tags":{"building":"yes"}},"w753":{"id":"w753","nodes":["n4369","n4370","n4371","n4372","n4375","n4369"],"tags":{"building":"yes"}},"w754":{"id":"w754","nodes":["n4373","n4374","n4375"],"tags":{"barrier":"fence"}},"w755":{"id":"w755","nodes":["n4376","n4377","n4378","n4379","n4376"],"tags":{"building":"shed"}},"w756":{"id":"w756","nodes":["n4380","n4381","n4382","n4383","n4384","n4385","n4386","n4387","n4388","n4389","n4390","n4391","n4380"],"tags":{"building":"yes"}},"w757":{"id":"w757","nodes":["n4392","n4393","n4394","n4395","n4392"],"tags":{"building":"yes"}},"w758":{"id":"w758","nodes":["n4396","n4397","n4398","n4399","n4396"],"tags":{"building":"shed"}},"w759":{"id":"w759","nodes":["n4400","n4401","n4402","n4403","n4404","n4405","n4406","n4407","n4408","n4409","n4410","n4411","n4412","n4413","n4414","n4415","n4400"],"tags":{"building":"yes"}},"w76":{"id":"w76","nodes":["n2561","n359","n2563","n2793","n357","n356","n2792","n355","n354","n2791","n2562","n353","n352","n358","n2561"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w760":{"id":"w760","nodes":["n4416","n4417"],"tags":{"barrier":"fence"}},"w761":{"id":"w761","nodes":["n4418","n4416","n4419"],"tags":{"barrier":"fence"}},"w762":{"id":"w762","nodes":["n4420","n4421"],"tags":{"barrier":"fence"}},"w763":{"id":"w763","nodes":["n4422","n4423","n4424","n4425","n4426","n4427","n4428","n4429","n4430","n4431","n4432","n4433","n4422"],"tags":{"building":"yes"}},"w764":{"id":"w764","nodes":["n4434","n4435","n4436","n4437","n4438","n4439","n4440","n4441","n4442","n4445","n4444","n4443","n4434"],"tags":{"building":"yes"}},"w765":{"id":"w765","nodes":["n4446","n4447","n4448","n4449","n4446"],"tags":{"building":"yes"}},"w766":{"id":"w766","nodes":["n4450","n4451","n4452","n4453","n4450"],"tags":{"building":"yes"}},"w767":{"id":"w767","nodes":["n4454","n4455","n4456","n4457","n4454"],"tags":{"building":"yes"}},"w768":{"id":"w768","nodes":["n4461","n4458","n4460"],"tags":{"footway":"crossing","highway":"footway"}},"w769":{"id":"w769","nodes":["n4460","n4462","n4459"],"tags":{"footway":"sidewalk","highway":"footway"}},"w77":{"id":"w77","nodes":["n325","n360","n361"],"tags":{"footway":"crossing","highway":"footway"}},"w770":{"id":"w770","nodes":["n4462","n4463","n4464"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w771":{"id":"w771","nodes":["n4464","n4465","n4466","n4467"],"tags":{"footway":"sidewalk","highway":"footway"}},"w772":{"id":"w772","nodes":["n3959","n3968","n3971","n3960","n3961","n3962","n3963"],"tags":{"footway":"sidewalk","highway":"footway"}},"w773":{"id":"w773","nodes":["n4467","n4468","n3959"],"tags":{"footway":"crossing","highway":"footway"}},"w774":{"id":"w774","nodes":["n4459","n4469","n4470"],"tags":{"footway":"crossing","highway":"footway"}},"w775":{"id":"w775","nodes":["n4470","n4471","n4472","n4473","n4474","n4475"],"tags":{"footway":"sidewalk","highway":"footway"}},"w776":{"id":"w776","nodes":["n4475","n4476","n4477"],"tags":{"footway":"crossing","highway":"footway"}},"w777":{"id":"w777","nodes":["n4477","n4478","n4479","n4480","n4481","n4482","n4483","n4484","n4485","n4486","n4487"],"tags":{"footway":"sidewalk","highway":"footway"}},"w778":{"id":"w778","nodes":["n4488","n4489","n4490","n4491","n4488"],"tags":{"building":"yes"}},"w779":{"id":"w779","nodes":["n4492","n4493","n4494","n4495","n4492"],"tags":{"building":"yes"}},"w78":{"id":"w78","nodes":["n361","n362","n369"],"tags":{"footway":"sidewalk","highway":"footway"}},"w780":{"id":"w780","nodes":["n4496","n4497","n4498","n4499","n4496"],"tags":{"access":"private","leisure":"swimming_pool"}},"w781":{"id":"w781","nodes":["n4508","n4509"],"tags":{"footway":"sidewalk","highway":"footway"}},"w782":{"id":"w782","nodes":["n4510","n4511"],"tags":{"footway":"sidewalk","highway":"footway"}},"w783":{"id":"w783","nodes":["n4512","n4513"],"tags":{"footway":"sidewalk","highway":"footway"}},"w784":{"id":"w784","nodes":["n4513","n4514"],"tags":{"footway":"sidewalk","highway":"footway"}},"w785":{"id":"w785","nodes":["n4515","n4516"],"tags":{"footway":"sidewalk","highway":"footway"}},"w786":{"id":"w786","nodes":["n4517","n4515"],"tags":{"footway":"sidewalk","highway":"footway"}},"w787":{"id":"w787","nodes":["n4518","n4519"],"tags":{"footway":"sidewalk","highway":"footway"}},"w788":{"id":"w788","nodes":["n4519","n4520","n4513"],"tags":{"footway":"crossing","highway":"footway"}},"w789":{"id":"w789","nodes":["n4515","n4521","n4513"],"tags":{"footway":"crossing","highway":"footway"}},"w79":{"id":"w79","nodes":["n362","n363","n334"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w790":{"id":"w790","nodes":["n4515","n4522","n4523"],"tags":{"footway":"crossing","highway":"footway"}},"w791":{"id":"w791","nodes":["n4523","n4524","n4519"],"tags":{"footway":"crossing","highway":"footway"}},"w792":{"id":"w792","nodes":["n4523","n4525"],"tags":{"footway":"sidewalk","highway":"footway"}},"w793":{"id":"w793","nodes":["n4525","n4526","n4527"],"tags":{"footway":"crossing","highway":"footway"}},"w794":{"id":"w794","nodes":["n4527","n4529"],"tags":{"footway":"sidewalk","highway":"footway"}},"w795":{"id":"w795","nodes":["n4529","n4530","n4518"],"tags":{"footway":"crossing","highway":"footway"}},"w796":{"id":"w796","nodes":["n4518","n4531"],"tags":{"footway":"sidewalk","highway":"footway"}},"w797":{"id":"w797","nodes":["n4531","n4532"],"tags":{"footway":"sidewalk","highway":"footway"}},"w798":{"id":"w798","nodes":["n4533","n4534"],"tags":{"footway":"sidewalk","highway":"footway"}},"w799":{"id":"w799","nodes":["n4518","n4538","n4539"],"tags":{"footway":"crossing","highway":"footway"}},"w8":{"id":"w8","nodes":["n46","n47","n145","n48","n49","n46"],"tags":{"amenity":"parking"}},"w80":{"id":"w80","nodes":["n334","n364","n365"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w800":{"id":"w800","nodes":["n4539","n4540","n4541"],"tags":{"footway":"crossing","highway":"footway"}},"w801":{"id":"w801","nodes":["n4541","n4542","n4529"],"tags":{"footway":"crossing","highway":"footway"}},"w802":{"id":"w802","nodes":["n4552","n4553"],"tags":{"footway":"sidewalk","highway":"footway"}},"w803":{"id":"w803","nodes":["n4554","n4555","n4556","n4557","n4558","n4559","n4554"],"tags":{"building":"yes"}},"w804":{"id":"w804","nodes":["n4562","n4563"],"tags":{"barrier":"retaining_wall"}},"w805":{"id":"w805","nodes":["n4568","n4569","n4570","n4571","n4568"],"tags":{"building":"yes"}},"w806":{"id":"w806","nodes":["n3473","n4575","n4576","n4581","n4580","n3551"],"tags":{"highway":"residential","oneway":"yes"}},"w807":{"id":"w807","nodes":["n4613","n4614","n4615","n4616","n4617","n4618","n4619","n4620","n4613"],"tags":{"leisure":"pitch","sport":"baseball"}},"w808":{"id":"w808","nodes":["n4621","n4622","n4623","n4624","n4625","n4626","n4627","n4628","n4629","n4630"],"tags":{"highway":"service"}},"w809":{"id":"w809","nodes":["n4631","n4632","n4633","n4637","n4634","n4638","n4635","n4636"],"tags":{"highway":"service"}},"w81":{"id":"w81","nodes":["n365","n366","n367"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w810":{"id":"w810","nodes":["n4639","n4640","n4641"],"tags":{"barrier":"fence"}},"w811":{"id":"w811","nodes":["n4649","n4650","n4651","n4652","n4649"],"tags":{"building":"yes"}},"w812":{"id":"w812","nodes":["n4654","n4655"],"tags":{"barrier":"fence"}},"w813":{"id":"w813","nodes":["n4656","n4657"],"tags":{"barrier":"fence"}},"w814":{"id":"w814","nodes":["n4669","n4670","n4671","n4672","n4669"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelters"}},"w815":{"id":"w815","nodes":["n4678","n4679","n4680","n1889"],"tags":{"highway":"service"}},"w816":{"id":"w816","nodes":["n239","n4686","n4687"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w817":{"id":"w817","nodes":["n4687","n4688","n4689"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w818":{"id":"w818","nodes":["n4689","n4690","n307"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w819":{"id":"w819","nodes":["n2266","n4743"],"tags":{"highway":"path"}},"w82":{"id":"w82","nodes":["n724","n368","n369"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w820":{"id":"w820","nodes":["n4785","n4786","n4787","n4788","n1684","n4760","n4769","n4761","n4762","n4763","n4764","n4765","n4766","n4767","n4768","n4785"],"tags":{"natural":"wood"}},"w821":{"id":"w821","nodes":["n4769","n4770","n4771","n4772","n4773","n4774","n4775","n4776","n4777","n4778","n4779","n4780","n4781","n4782","n4783","n4784","n4785","n4768","n4767","n4766","n4765","n4764","n4763","n4762","n4761","n4769"],"tags":{"natural":"scrub"}},"w822":{"id":"w822","nodes":["n4772","n4789","n4790","n4791","n4792","n4793","n4794","n4795","n4796","n4797","n4798","n4799","n4783","n4782","n4781","n4780","n4779","n4778","n4777","n4776","n4775","n4774","n4773","n4772"],"tags":{"natural":"wood"}},"w823":{"id":"w823","nodes":["n4800","n4801","n4802","n4803","n4804","n4805","n4806","n4807","n4808","n4809","n4810","n4811","n4812","n4813","n4814","n4815","n4816","n3490","n3489","n4800"],"tags":{"natural":"wood"}},"w824":{"id":"w824","nodes":["n4817","n4818","n4819","n4820","n4821","n4822","n4817"],"tags":{"landuse":"recreation_ground"}},"w825":{"id":"w825","nodes":["n4563","n4823","n4824","n4829","n4825","n4826","n4827","n4828","n4562","n4563"],"tags":{"landuse":"recreation_ground"}},"w826":{"id":"w826","nodes":["n4830","n4831","n4832","n4833","n4834","n4835","n4836","n4830"],"tags":{"landuse":"industrial"}},"w827":{"id":"w827","nodes":["n4563","n4837","n4838","n4839","n4840","n4841","n4842","n4827","n4828","n4562","n4563"],"tags":{"landuse":"industrial"}},"w828":{"id":"w828","nodes":["n4843","n4844","n4845","n4846","n4843"],"tags":{"landuse":"farmland"}},"w829":{"id":"w829","nodes":["n3712","n4847","n4848","n4849","n4850","n4851","n4852","n4858","n4864","n4959","n4960","n4853","n4857","n4854","n4855","n4856","n3712"],"tags":{"aeroway":"aerodrome","name":"Three Rivers Municipal Airport"}},"w83":{"id":"w83","nodes":["n371","n372","n373","n374","n371"],"tags":{"building":"yes"}},"w830":{"id":"w830","nodes":["n4855","n4854","n4857","n4853","n4960"],"tags":{"barrier":"fence"}},"w831":{"id":"w831","nodes":["n4860","n4859","n4858","n4852","n4851"],"tags":{"barrier":"fence"}},"w832":{"id":"w832","nodes":["n4866","n4878","n4869","n4867"],"tags":{"aeroway":"runway","ref":"5/23"}},"w833":{"id":"w833","nodes":["n4868","n4890","n4894","n4881","n4869","n4905","n4870"],"tags":{"aeroway":"runway","ref":"9/27"}},"w834":{"id":"w834","nodes":["n4871","n4875","n4872","n4895","n4873","n4874","n4871"],"tags":{"aeroway":"apron"}},"w835":{"id":"w835","nodes":["n4875","n4876","n4877","n4878","n4879","n4880","n4882","n4881"],"tags":{"aeroway":"taxiway"}},"w836":{"id":"w836","nodes":["n4882","n4893","n4883","n4891","n4884","n4885","n4886","n4887","n4888","n4892","n4889","n4890"],"tags":{"aeroway":"taxiway"}},"w837":{"id":"w837","nodes":["n4893","n4894"],"tags":{"aeroway":"taxiway"}},"w838":{"id":"w838","nodes":["n4895","n4896","n4897","n4898","n4899","n4900","n4901","n4902","n4903","n4906","n4904","n4905"],"tags":{"aeroway":"taxiway"}},"w839":{"id":"w839","nodes":["n4907","n4908"],"tags":{"highway":"service"}},"w84":{"id":"w84","nodes":["n374","n375","n376","n377","n373","n374"],"tags":{"building":"yes"}},"w840":{"id":"w840","nodes":["n4909","n4907","n4910"],"tags":{"highway":"service"}},"w841":{"id":"w841","nodes":["n4911","n4912","n4913","n4914","n4911"],"tags":{"building":"yes"}},"w842":{"id":"w842","nodes":["n4915","n4916","n4917","n4918","n4915"],"tags":{"aeroway":"hangar","building":"yes"}},"w843":{"id":"w843","nodes":["n4919","n4920","n4921","n4922","n4919"],"tags":{"building":"yes"}},"w844":{"id":"w844","nodes":["n4923","n4924","n4925","n4926","n4923"],"tags":{"aeroway":"hangar","building":"yes"}},"w845":{"id":"w845","nodes":["n4927","n4928","n4929","n4930","n4927"],"tags":{"aeroway":"hangar","building":"yes"}},"w846":{"id":"w846","nodes":["n4931","n4932","n4933","n4934","n4931"],"tags":{"aeroway":"hangar","building":"yes"}},"w847":{"id":"w847","nodes":["n4935","n4936","n4937","n4938","n4935"],"tags":{"aeroway":"hangar","building":"yes"}},"w848":{"id":"w848","nodes":["n4939","n4940","n4941","n4942","n4939"],"tags":{"aeroway":"hangar","building":"yes"}},"w849":{"id":"w849","nodes":["n4943","n4944","n4945","n4946","n4943"],"tags":{"aeroway":"hangar","building":"yes"}},"w85":{"id":"w85","nodes":["n431","n432","n1038","n433","n434","n1040","n431"],"tags":{"building":"yes"}},"w850":{"id":"w850","nodes":["n4947","n4948","n4949","n4950","n4947"],"tags":{"aeroway":"hangar","building":"yes"}},"w851":{"id":"w851","nodes":["n4951","n4952","n4953","n4954","n4951"],"tags":{"aeroway":"hangar","building":"yes"}},"w852":{"id":"w852","nodes":["n4955","n4956","n4957","n4958","n4955"],"tags":{"aeroway":"hangar","building":"yes"}},"w853":{"id":"w853","nodes":["n4959","n4864","n4861","n4862","n4863"],"tags":{"barrier":"fence"}},"w854":{"id":"w854","nodes":["n4961","n4962","n4963","n4964","n4965","n4966","n4967","n4968","n4969","n4961"],"tags":{"landuse":"farmland"}},"w855":{"id":"w855","nodes":["n4970","n4971","n4972","n4973","n4974","n4975","n4976","n4977","n4978","n4980","n4970"],"tags":{"landuse":"farmland"}},"w856":{"id":"w856","nodes":["n4979","n4980","n4978","n4981","n4982","n4983","n4984","n4985","n4979"],"tags":{"natural":"scrub"}},"w857":{"id":"w857","nodes":["n4986","n4987","n4988","n5032","n4989","n4990","n4991","n4992","n4993","n4994","n4995","n4996","n4997","n4998","n4999","n5000","n5001","n5002","n5022","n5023","n5024","n5025","n5030","n5031","n5029","n5028","n5027","n5026","n4986"],"tags":{"landuse":"farmland"}},"w858":{"id":"w858","nodes":["n5001","n5003","n5004","n4999","n5000","n5001"],"tags":{"natural":"scrub"}},"w859":{"id":"w859","nodes":["n5005","n5006","n5007","n5008","n5009","n5010","n5021","n5020","n5019","n5011","n5012","n5013","n5018","n5014","n5015","n5017","n5016","n5005"],"tags":{"landuse":"farmland"}},"w86":{"id":"w86","nodes":["n384","n385","n386","n387","n384"],"tags":{"building":"yes"}},"w860":{"id":"w860","nodes":["n3020","n5033","n5034","n5035","n3179","n3180","n3191","n3181","n3190","n3182","n3183","n3184","n3185","n3186","n3187","n3188","n3189","n3160","n3161","n3162","n2126","n2153","n2288","n3020"],"tags":{"landuse":"industrial"}},"w87":{"id":"w87","nodes":["n387","n388","n389","n386","n387"],"tags":{"building":"yes"}},"w88":{"id":"w88","nodes":["n390","n391","n392","n393","n390"],"tags":{"building":"yes"}},"w89":{"id":"w89","nodes":["n394","n2895"],"tags":{"highway":"service"}},"w9":{"id":"w9","nodes":["n50","n51","n148","n52","n57","n891","n53","n50"],"tags":{"building":"yes"}},"w90":{"id":"w90","nodes":["n398","n399","n400","n401","n402","n403","n404","n405","n406","n407","n408","n409","n410","n411","n412","n413","n414","n415","n416","n417","n398"],"tags":{"building":"yes"}},"w91":{"id":"w91","nodes":["n418","n423","n419"],"tags":{"highway":"service"}},"w92":{"id":"w92","nodes":["n420","n421","n422","n423","n420"],"tags":{"amenity":"parking"}},"w93":{"id":"w93","nodes":["n2282","n1876"],"tags":{"name":"Rocky River","tunnel":"building_passage","waterway":"river"}},"w94":{"id":"w94","nodes":["n1876","n885","n1875","n2234"],"tags":{"name":"Rocky River","waterway":"river"}},"w95":{"id":"w95","nodes":["n425","n426","n427","n914","n428","n913","n425"],"tags":{"building":"yes"}},"w96":{"id":"w96","nodes":["n456","n620","n1034","n1035","n456"],"tags":{"building":"yes"}},"w97":{"id":"w97","nodes":["n435","n912","n451","n321"],"tags":{"highway":"footway"}},"w98":{"id":"w98","nodes":["n436","n319","n437","n438","n439","n440","n441","n476","n442"],"tags":{"highway":"service"}},"w99":{"id":"w99","nodes":["n443","n444","n445","n446","n447","n448","n449","n450","n443"],"tags":{"amenity":"parking"}}};
60519
60520 // toggles the visibility of ui elements, using a combination of the
60521 // hide class, which sets display=none, and a d3 transition for opacity.
60522 // this will cause blinking when called repeatedly, so check that the
60523 // value actually changes between calls.
60524 function uiToggle(show, callback) {
60525     return function(selection$$1) {
60526         selection$$1
60527             .style('opacity', show ? 0 : 1)
60528             .classed('hide', false)
60529             .transition()
60530             .style('opacity', show ? 1 : 0)
60531             .on('end', function() {
60532                 select(this)
60533                     .classed('hide', !show)
60534                     .style('opacity', null);
60535                 if (callback) callback.apply(this);
60536             });
60537     };
60538 }
60539
60540 // Tooltips and svg mask used to highlight certain features
60541 function uiCurtain() {
60542
60543     var surface = select(null),
60544         tooltip = select(null),
60545         darkness = select(null);
60546
60547     function curtain(selection$$1) {
60548         surface = selection$$1
60549             .append('svg')
60550             .attr('id', 'curtain')
60551             .style('z-index', 1000)
60552             .style('pointer-events', 'none')
60553             .style('position', 'absolute')
60554             .style('top', 0)
60555             .style('left', 0);
60556
60557         darkness = surface.append('path')
60558             .attr('x', 0)
60559             .attr('y', 0)
60560             .attr('class', 'curtain-darkness');
60561
60562         select(window).on('resize.curtain', resize);
60563
60564         tooltip = selection$$1.append('div')
60565             .attr('class', 'tooltip')
60566             .style('z-index', 1002);
60567
60568         tooltip
60569             .append('div')
60570             .attr('class', 'tooltip-arrow');
60571
60572         tooltip
60573             .append('div')
60574             .attr('class', 'tooltip-inner');
60575
60576         resize();
60577
60578
60579         function resize() {
60580             surface
60581                 .attr('width', window.innerWidth)
60582                 .attr('height', window.innerHeight);
60583             curtain.cut(darkness.datum());
60584         }
60585     }
60586
60587
60588     /**
60589      * Reveal cuts the curtain to highlight the given box,
60590      * and shows a tooltip with instructions next to the box.
60591      *
60592      * @param  {String|ClientRect} [box]   box used to cut the curtain
60593      * @param  {String}    [text]          text for a tooltip
60594      * @param  {Object}    [options]
60595      * @param  {string}    [options.tooltipClass]    optional class to add to the tooltip
60596      * @param  {integer}   [options.duration]        transition time in milliseconds
60597      * @param  {string}    [options.buttonText]      if set, create a button with this text label
60598      * @param  {function}  [options.buttonCallback]  if set, the callback for the button
60599      * @param  {String|ClientRect} [options.tooltipBox]  box for tooltip position, if different from box for the curtain
60600      */
60601     curtain.reveal = function(box, text$$1, options) {
60602         if (typeof box === 'string') {
60603             box = select(box).node();
60604         }
60605         if (box && box.getBoundingClientRect) {
60606             box = copyBox(box.getBoundingClientRect());
60607         }
60608
60609         options = options || {};
60610
60611         var tooltipBox;
60612         if (options.tooltipBox) {
60613             tooltipBox = options.tooltipBox;
60614             if (typeof tooltipBox === 'string') {
60615                 tooltipBox = select(tooltipBox).node();
60616             }
60617             if (tooltipBox && tooltipBox.getBoundingClientRect) {
60618                 tooltipBox = copyBox(tooltipBox.getBoundingClientRect());
60619             }
60620         } else {
60621             tooltipBox = box;
60622         }
60623
60624         if (tooltipBox && text$$1) {
60625             // pseudo markdown bold text for the instruction section..
60626             var parts = text$$1.split('**');
60627             var html$$1 = parts[0] ? '<span>' + parts[0] + '</span>' : '';
60628             if (parts[1]) {
60629                 html$$1 += '<span class="instruction">' + parts[1] + '</span>';
60630             }
60631
60632             html$$1 = html$$1.replace(/\*(.*?)\*/g, '<em>$1</em>');   // emphasis
60633             html$$1 = html$$1.replace(/\{br\}/g, '<br/><br/>');       // linebreak
60634
60635             if (options.buttonText && options.buttonCallback) {
60636                 html$$1 += '<div class="button-section">' +
60637                     '<button href="#" class="button action col8">' + options.buttonText + '</button></div>';
60638             }
60639
60640             var classes = 'curtain-tooltip tooltip in ' + (options.tooltipClass || '');
60641             tooltip
60642                 .classed(classes, true)
60643                 .selectAll('.tooltip-inner')
60644                 .html(html$$1);
60645
60646             if (options.buttonText && options.buttonCallback) {
60647                 var button = tooltip.selectAll('.button-section .button.action');
60648                 button
60649                     .on('click', function() {
60650                         event.preventDefault();
60651                         options.buttonCallback();
60652                     });
60653             }
60654
60655             var tip = copyBox(tooltip.node().getBoundingClientRect()),
60656                 w = window.innerWidth,
60657                 h = window.innerHeight,
60658                 tooltipWidth = 200,
60659                 tooltipArrow = 5,
60660                 side, pos;
60661
60662
60663             // hack: this will have bottom placement,
60664             // so need to reserve extra space for the tooltip illustration.
60665             if (options.tooltipClass === 'intro-mouse') {
60666                 tip.height += 80;
60667             }
60668
60669             // trim box dimensions to just the portion that fits in the window..
60670             if (tooltipBox.top + tooltipBox.height > h) {
60671                 tooltipBox.height -= (tooltipBox.top + tooltipBox.height - h);
60672             }
60673             if (tooltipBox.left + tooltipBox.width > w) {
60674                 tooltipBox.width -= (tooltipBox.left + tooltipBox.width - w);
60675             }
60676
60677             // determine tooltip placement..
60678
60679             if (tooltipBox.top + tooltipBox.height < 100) {
60680                 // tooltip below box..
60681                 side = 'bottom';
60682                 pos = [
60683                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
60684                     tooltipBox.top + tooltipBox.height
60685                 ];
60686
60687             } else if (tooltipBox.top > h - 140) {
60688                 // tooltip above box..
60689                 side = 'top';
60690                 pos = [
60691                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
60692                     tooltipBox.top - tip.height
60693                 ];
60694
60695             } else {
60696                 // tooltip to the side of the tooltipBox..
60697                 var tipY = tooltipBox.top + tooltipBox.height / 2 - tip.height / 2;
60698
60699                 if (textDirection === 'rtl') {
60700                     if (tooltipBox.left - tooltipWidth - tooltipArrow < 70) {
60701                         side = 'right';
60702                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
60703
60704                     } else {
60705                         side = 'left';
60706                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
60707                     }
60708
60709                 } else {
60710                     if (tooltipBox.left + tooltipBox.width + tooltipArrow + tooltipWidth > w - 70) {
60711                         side = 'left';
60712                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
60713                     }
60714                     else {
60715                         side = 'right';
60716                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
60717                     }
60718                 }
60719             }
60720
60721             if (options.duration !== 0 || !tooltip.classed(side)) {
60722                 tooltip.call(uiToggle(true));
60723             }
60724
60725             tooltip
60726                 .style('top', pos[1] + 'px')
60727                 .style('left', pos[0] + 'px')
60728                 .attr('class', classes + ' ' + side);
60729
60730
60731             // shift tooltip-inner if it is very close to the top or bottom edge
60732             // (doesn't affect the placement of the tooltip-arrow)
60733             var shiftY = 0;
60734             if (side === 'left' || side === 'right') {
60735                 if (pos[1] < 60) {
60736                     shiftY = 60 - pos[1];
60737                 }
60738                 else if (pos[1] + tip.height > h - 100) {
60739                     shiftY = h - pos[1] - tip.height - 100;
60740                 }
60741             }
60742             tooltip.selectAll('.tooltip-inner')
60743                 .style('top', shiftY + 'px');
60744
60745         } else {
60746             tooltip
60747                 .classed('in', false)
60748                 .call(uiToggle(false));
60749         }
60750
60751         curtain.cut(box, options.duration);
60752
60753         return tooltip;
60754     };
60755
60756
60757     curtain.cut = function(datum, duration) {
60758         darkness.datum(datum)
60759             .interrupt();
60760
60761         var selection$$1;
60762         if (duration === 0) {
60763             selection$$1 = darkness;
60764         } else {
60765             selection$$1 = darkness
60766                 .transition()
60767                 .duration(duration || 600)
60768                 .ease(linear$1);
60769         }
60770
60771         selection$$1
60772             .attr('d', function(d) {
60773                 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
60774                     window.innerWidth + ',' + window.innerHeight + 'L' +
60775                     window.innerWidth + ',0 Z';
60776
60777                 if (!d) return string;
60778                 return string + 'M' +
60779                     d.left + ',' + d.top + 'L' +
60780                     d.left + ',' + (d.top + d.height) + 'L' +
60781                     (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
60782                     (d.left + d.width) + ',' + (d.top) + 'Z';
60783
60784             });
60785     };
60786
60787
60788     curtain.remove = function() {
60789         surface.remove();
60790         tooltip.remove();
60791         select(window).on('resize.curtain', null);
60792     };
60793
60794
60795     // ClientRects are immutable, so copy them to an object,
60796     // in case we need to trim the height/width.
60797     function copyBox(src) {
60798         return {
60799             top: src.top,
60800             right: src.right,
60801             bottom: src.bottom,
60802             left: src.left,
60803             width: src.width,
60804             height: src.height
60805         };
60806     }
60807
60808
60809     return curtain;
60810 }
60811
60812 function uiIntroWelcome(context, reveal) {
60813     var dispatch$$1 = dispatch('done'),
60814         listener = clickListener();
60815
60816     var chapter = {
60817         title: 'intro.welcome.title'
60818     };
60819
60820
60821     function welcome() {
60822         context.map().centerZoom([-85.63591, 41.94285], 19);
60823         reveal('.intro-nav-wrap .chapter-welcome',
60824             t('intro.welcome.welcome'),
60825             { buttonText: t('intro.ok'), buttonCallback: practice }
60826         );
60827     }
60828
60829     function practice() {
60830         reveal('.intro-nav-wrap .chapter-welcome',
60831             t('intro.welcome.practice'),
60832             { buttonText: t('intro.ok'), buttonCallback: words }
60833         );
60834     }
60835
60836     function words() {
60837         reveal('.intro-nav-wrap .chapter-welcome',
60838             t('intro.welcome.words'),
60839             { buttonText: t('intro.ok'), buttonCallback: mouse$$1 }
60840         );
60841     }
60842
60843
60844     function mouse$$1() {
60845         reveal('.intro-nav-wrap .chapter-welcome',
60846             t('intro.welcome.mouse'),
60847             { buttonText: t('intro.ok'), buttonCallback: leftClick }
60848         );
60849     }
60850
60851
60852     function leftClick() {
60853         var counter = 0,
60854             times = 5;
60855
60856         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
60857             t('intro.welcome.leftclick', { num: times }),
60858             { tooltipClass: 'intro-mouse' }
60859         );
60860
60861         tooltip.selectAll('.tooltip-inner')
60862             .insert('svg', 'span')
60863             .attr('class', 'tooltip-illustration')
60864             .append('use')
60865             .attr('xlink:href', '#walkthrough-mouse');
60866
60867         tooltip
60868             .append('div')
60869             .attr('class', 'counter');
60870
60871         tooltip.call(listener);
60872
60873         listener.on('click', function(which) {
60874             if (which === 'left') {
60875                 select('.curtain-tooltip.intro-mouse .counter')
60876                     .text(String(++counter));
60877
60878                 if (counter === times) {
60879                     window.setTimeout(function() { continueTo(rightClick); }, 1000);
60880                 }
60881             }
60882         });
60883
60884         function continueTo(nextStep) {
60885             listener.on('click', null);
60886             tooltip.call(listener.off);
60887             tooltip.select('.counter').remove();
60888             nextStep();
60889         }
60890     }
60891
60892
60893     function rightClick() {
60894         var counter = 0,
60895             times = 5;
60896
60897         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
60898             t('intro.welcome.rightclick', { num: times }),
60899             { tooltipClass: 'intro-mouse' }
60900         );
60901
60902         tooltip.selectAll('.tooltip-inner')
60903             .insert('svg', 'span')
60904             .attr('class', 'tooltip-illustration')
60905             .append('use')
60906             .attr('xlink:href', '#walkthrough-mouse');
60907
60908         tooltip
60909             .append('div')
60910             .attr('class', 'counter');
60911
60912         tooltip.call(listener);
60913
60914         listener.on('click', function(which) {
60915             if (which === 'right') {
60916                 select('.curtain-tooltip.intro-mouse .counter')
60917                     .text(String(++counter));
60918
60919                 if (counter === times) {
60920                     window.setTimeout(function() { continueTo(chapters); }, 1000);
60921                 }
60922             }
60923         });
60924
60925         function continueTo(nextStep) {
60926             listener.on('click', null);
60927             tooltip.call(listener.off);
60928             tooltip.select('.counter').remove();
60929             nextStep();
60930         }
60931     }
60932
60933
60934     function chapters() {
60935         dispatch$$1.call('done');
60936         reveal('.intro-nav-wrap .chapter-navigation',
60937             t('intro.welcome.chapters', { next: t('intro.navigation.title') })
60938         );
60939     }
60940
60941
60942     chapter.enter = function() {
60943         welcome();
60944     };
60945
60946
60947     chapter.exit = function() {
60948         listener.off();
60949     };
60950
60951
60952     chapter.restart = function() {
60953         chapter.exit();
60954         chapter.enter();
60955     };
60956
60957
60958     return utilRebind(chapter, dispatch$$1, 'on');
60959 }
60960
60961
60962
60963 function clickListener() {
60964     var dispatch$$1 = dispatch('click'),
60965         minTime = 120,
60966         tooltip = select(null),
60967         down = {};
60968
60969     // `down` keeps track of which buttons/keys are down.
60970     // Setting a property in `down` happens immediately.
60971     // Unsetting a property in `down` is delayed because
60972     //   on Windows a contextmenu event happens after keyup/mouseup
60973
60974     function keydown() {
60975         if (event.keyCode === 93)  {   // context menu
60976             event.preventDefault();
60977             event.stopPropagation();
60978             down.menu = event.timeStamp;
60979             tooltip.classed('rightclick', true);
60980         }
60981     }
60982
60983
60984     function keyup() {
60985         if (event.keyCode === 93)  {   // context menu
60986             event.preventDefault();
60987             event.stopPropagation();
60988             var endTime = event.timeStamp,
60989                 startTime = down.menu || endTime,
60990                 delay = (endTime - startTime < minTime) ? minTime : 0;
60991
60992             window.setTimeout(function() {
60993                 tooltip.classed('rightclick', false);
60994                 down.menu = undefined;  // delayed, for Windows
60995             }, delay);
60996
60997             dispatch$$1.call('click', this, 'right');
60998         }
60999     }
61000
61001
61002     function mousedown() {
61003         var button = event.button;
61004         if (button === 0 && !event.ctrlKey) {
61005             tooltip.classed('leftclick', true);
61006         } else if (button === 2) {
61007             tooltip.classed('rightclick', true);
61008         }
61009         down[button] = event.timeStamp;
61010     }
61011
61012
61013     function mouseup() {
61014         var button = event.button,
61015             endTime = event.timeStamp,
61016             startTime = down[button] || endTime,
61017             delay = (endTime - startTime < minTime) ? minTime : 0;
61018
61019         if (button === 0 && !event.ctrlKey) {
61020             window.setTimeout(function() {
61021                 tooltip.classed('leftclick', false);
61022                 down[button] = undefined;  // delayed, for Windows
61023             }, delay);
61024
61025             dispatch$$1.call('click', this, 'left');
61026
61027         } else if (button === 2) {
61028             window.setTimeout(function() {
61029                 tooltip.classed('rightclick', false);
61030                 down[button] = undefined;  // delayed, for Windows
61031             }, delay);
61032
61033             dispatch$$1.call('click', this, 'right');
61034
61035         } else {
61036             window.setTimeout(function() {
61037                 down[button] = undefined;  // delayed, for Windows
61038             }, delay);
61039         }
61040     }
61041
61042
61043     function contextmenu() {
61044         event.preventDefault();
61045         event.stopPropagation();
61046         if (!down[2] && !down.menu) {
61047             tooltip.classed('rightclick', true);
61048             window.setTimeout(function() {
61049                 tooltip.classed('rightclick', false);
61050             }, minTime);
61051             dispatch$$1.call('click', this, 'right');
61052         }
61053     }
61054
61055
61056     var behavior = function(selection$$1) {
61057         tooltip = selection$$1;
61058         down = {};
61059
61060         select(window)
61061             .on('keydown.intro', keydown)
61062             .on('keyup.intro', keyup)
61063             .on('mousedown.intro', mousedown)
61064             .on('mouseup.intro', mouseup)
61065             .on('contextmenu.intro', contextmenu);
61066     };
61067
61068
61069     behavior.off = function() {
61070         select(window)
61071             .on('keydown.intro', null)
61072             .on('keyup.intro', null)
61073             .on('mousedown.intro', null)
61074             .on('mouseup.intro', null)
61075             .on('contextmenu.intro', null);
61076
61077         tooltip
61078             .classed('leftclick', false)
61079             .classed('rightclick', false);
61080     };
61081
61082     return utilRebind(behavior, dispatch$$1, 'on');
61083 }
61084
61085 function uiIntroNavigation(context, reveal) {
61086     var dispatch$$1 = dispatch('done'),
61087         timeouts = [],
61088         hallId = 'n2061',
61089         townHall = [-85.63591, 41.94285],
61090         springStreetId = 'w397',
61091         springStreetEndId = 'n1834',
61092         springStreet = [-85.63582, 41.94255],
61093         onewayField = context.presets().field('oneway'),
61094         maxspeedField = context.presets().field('maxspeed');
61095
61096
61097     var chapter = {
61098         title: 'intro.navigation.title'
61099     };
61100
61101
61102     function timeout(f, t$$1) {
61103         timeouts.push(window.setTimeout(f, t$$1));
61104     }
61105
61106
61107     function eventCancel() {
61108         event.stopPropagation();
61109         event.preventDefault();
61110     }
61111
61112
61113     function isTownHallSelected() {
61114         var ids = context.selectedIDs();
61115         return ids.length === 1 && ids[0] === hallId;
61116     }
61117
61118
61119     function dragMap() {
61120         context.enter(modeBrowse(context));
61121         context.history().reset('initial');
61122
61123         var msec = transitionTime(townHall, context.map().center());
61124         if (msec) { reveal(null, null, { duration: 0 }); }
61125         context.map().zoom(19).centerEase(townHall, msec);
61126
61127         timeout(function() {
61128             var centerStart = context.map().center();
61129
61130             reveal('#surface', t('intro.navigation.drag'));
61131             context.map().on('drawn.intro', function() {
61132                 reveal('#surface', t('intro.navigation.drag'), { duration: 0 });
61133             });
61134
61135             context.map().on('move.intro', function() {
61136                 var centerNow = context.map().center();
61137                 if (centerStart[0] !== centerNow[0] || centerStart[1] !== centerNow[1]) {
61138                     context.map().on('move.intro', null);
61139                     timeout(function() { continueTo(zoomMap); }, 3000);
61140                 }
61141             });
61142
61143         }, msec + 100);
61144
61145         function continueTo(nextStep) {
61146             context.map().on('move.intro drawn.intro', null);
61147             nextStep();
61148         }
61149     }
61150
61151
61152     function zoomMap() {
61153         var zoomStart = context.map().zoom();
61154
61155         reveal('#surface',
61156             t('intro.navigation.zoom', {
61157                 plus: icon('#icon-plus', 'pre-text'),
61158                 minus: icon('#icon-minus', 'pre-text')
61159             })
61160         );
61161
61162         context.map().on('drawn.intro', function() {
61163             reveal('#surface',
61164                 t('intro.navigation.zoom', {
61165                     plus: icon('#icon-plus', 'pre-text'),
61166                     minus: icon('#icon-minus', 'pre-text')
61167                 }), { duration: 0 }
61168             );
61169         });
61170
61171         context.map().on('move.intro', function() {
61172             if (context.map().zoom() !== zoomStart) {
61173                 context.map().on('move.intro', null);
61174                 timeout(function() { continueTo(features); }, 3000);
61175             }
61176         });
61177
61178         function continueTo(nextStep) {
61179             context.map().on('move.intro drawn.intro', null);
61180             nextStep();
61181         }
61182     }
61183
61184
61185     function features() {
61186         var onClick = function() { continueTo(pointsLinesAreas); };
61187
61188         reveal('#surface', t('intro.navigation.features'),
61189             { buttonText: t('intro.ok'), buttonCallback: onClick }
61190         );
61191
61192         context.map().on('drawn.intro', function() {
61193             reveal('#surface', t('intro.navigation.features'),
61194                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
61195             );
61196         });
61197
61198         function continueTo(nextStep) {
61199             context.map().on('drawn.intro', null);
61200             nextStep();
61201         }
61202     }
61203
61204     function pointsLinesAreas() {
61205         var onClick = function() { continueTo(nodesWays); };
61206
61207         reveal('#surface', t('intro.navigation.points_lines_areas'),
61208             { buttonText: t('intro.ok'), buttonCallback: onClick }
61209         );
61210
61211         context.map().on('drawn.intro', function() {
61212             reveal('#surface', t('intro.navigation.points_lines_areas'),
61213                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
61214             );
61215         });
61216
61217         function continueTo(nextStep) {
61218             context.map().on('drawn.intro', null);
61219             nextStep();
61220         }
61221     }
61222
61223     function nodesWays() {
61224         var onClick = function() { continueTo(clickTownHall); };
61225
61226         reveal('#surface', t('intro.navigation.nodes_ways'),
61227             { buttonText: t('intro.ok'), buttonCallback: onClick }
61228         );
61229
61230         context.map().on('drawn.intro', function() {
61231             reveal('#surface', t('intro.navigation.nodes_ways'),
61232                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
61233             );
61234         });
61235
61236         function continueTo(nextStep) {
61237             context.map().on('drawn.intro', null);
61238             nextStep();
61239         }
61240     }
61241
61242     function clickTownHall() {
61243         context.enter(modeBrowse(context));
61244         context.history().reset('initial');
61245
61246         reveal(null, null, { duration: 0 });
61247         context.map().zoomEase(19, 500);
61248
61249         timeout(function() {
61250             var entity = context.hasEntity(hallId);
61251             if (!entity) return;
61252             context.map().centerEase(entity.loc, 500);
61253
61254             timeout(function() {
61255                 var entity = context.hasEntity(hallId);
61256                 if (!entity) return;
61257                 var box = pointBox(entity.loc, context);
61258                 reveal(box, t('intro.navigation.click_townhall'));
61259
61260                 context.map().on('move.intro drawn.intro', function() {
61261                     var entity = context.hasEntity(hallId);
61262                     if (!entity) return;
61263                     var box = pointBox(entity.loc, context);
61264                     reveal(box, t('intro.navigation.click_townhall'), { duration: 0 });
61265                 });
61266
61267                 context.on('enter.intro', function() {
61268                     if (isTownHallSelected()) continueTo(selectedTownHall);
61269                 });
61270
61271             }, 550);  // after centerEase
61272
61273         }, 550); // after zoomEase
61274
61275         context.history().on('change.intro', function() {
61276             if (!context.hasEntity(hallId)) {
61277                 continueTo(clickTownHall);
61278             }
61279         });
61280
61281         function continueTo(nextStep) {
61282             context.on('enter.intro', null);
61283             context.map().on('move.intro drawn.intro', null);
61284             context.history().on('change.intro', null);
61285             nextStep();
61286         }
61287     }
61288
61289
61290     function selectedTownHall() {
61291         if (!isTownHallSelected()) return clickTownHall();
61292
61293         var entity = context.hasEntity(hallId);
61294         if (!entity) return clickTownHall();
61295
61296         var box = pointBox(entity.loc, context);
61297         var onClick = function() { continueTo(editorTownHall); };
61298
61299         reveal(box, t('intro.navigation.selected_townhall'),
61300             { buttonText: t('intro.ok'), buttonCallback: onClick }
61301         );
61302
61303         context.map().on('move.intro drawn.intro', function() {
61304             var entity = context.hasEntity(hallId);
61305             if (!entity) return;
61306             var box = pointBox(entity.loc, context);
61307             reveal(box, t('intro.navigation.selected_townhall'),
61308                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
61309             );
61310         });
61311
61312         context.history().on('change.intro', function() {
61313             if (!context.hasEntity(hallId)) {
61314                 continueTo(clickTownHall);
61315             }
61316         });
61317
61318         function continueTo(nextStep) {
61319             context.map().on('move.intro drawn.intro', null);
61320             context.history().on('change.intro', null);
61321             nextStep();
61322         }
61323     }
61324
61325
61326     function editorTownHall() {
61327         if (!isTownHallSelected()) return clickTownHall();
61328
61329         // disallow scrolling
61330         select('.inspector-wrap').on('wheel.intro', eventCancel);
61331
61332         var onClick = function() { continueTo(presetTownHall); };
61333
61334         reveal('.entity-editor-pane',
61335             t('intro.navigation.editor_townhall'),
61336             { buttonText: t('intro.ok'), buttonCallback: onClick }
61337         );
61338
61339         context.on('exit.intro', function() {
61340             continueTo(clickTownHall);
61341         });
61342
61343         context.history().on('change.intro', function() {
61344             if (!context.hasEntity(hallId)) {
61345                 continueTo(clickTownHall);
61346             }
61347         });
61348
61349         function continueTo(nextStep) {
61350             context.on('exit.intro', null);
61351             context.history().on('change.intro', null);
61352             select('.inspector-wrap').on('wheel.intro', null);
61353             nextStep();
61354         }
61355     }
61356
61357
61358     function presetTownHall() {
61359         if (!isTownHallSelected()) return clickTownHall();
61360
61361         // reset pane, in case user happened to change it..
61362         select('.inspector-wrap .panewrap').style('right', '0%');
61363         // disallow scrolling
61364         select('.inspector-wrap').on('wheel.intro', eventCancel);
61365
61366         // preset match, in case the user happened to change it.
61367         var entity = context.entity(context.selectedIDs()[0]);
61368         var preset = context.presets().match(entity, context.graph());
61369
61370         var onClick = function() { continueTo(fieldsTownHall); };
61371
61372         context.on('exit.intro', function() {
61373             continueTo(clickTownHall);
61374         });
61375
61376         context.history().on('change.intro', function() {
61377             if (!context.hasEntity(hallId)) {
61378                 continueTo(clickTownHall);
61379             }
61380         });
61381
61382         reveal('.inspector-body .preset-list-item.inspector-inner',
61383             t('intro.navigation.preset_townhall', { preset: preset.name() }),
61384             { buttonText: t('intro.ok'), buttonCallback: onClick }
61385         );
61386
61387         function continueTo(nextStep) {
61388             context.on('exit.intro', null);
61389             context.history().on('change.intro', null);
61390             select('.inspector-wrap').on('wheel.intro', null);
61391             nextStep();
61392         }
61393     }
61394
61395
61396     function fieldsTownHall() {
61397         if (!isTownHallSelected()) return clickTownHall();
61398
61399         // reset pane, in case user happened to change it..
61400         select('.inspector-wrap .panewrap').style('right', '0%');
61401         // disallow scrolling
61402         select('.inspector-wrap').on('wheel.intro', eventCancel);
61403
61404         var onClick = function() { continueTo(closeTownHall); };
61405
61406         reveal('.inspector-body .preset-editor',
61407             t('intro.navigation.fields_townhall'),
61408             { buttonText: t('intro.ok'), buttonCallback: onClick }
61409         );
61410
61411         context.on('exit.intro', function() {
61412             continueTo(clickTownHall);
61413         });
61414
61415         context.history().on('change.intro', function() {
61416             if (!context.hasEntity(hallId)) {
61417                 continueTo(clickTownHall);
61418             }
61419         });
61420
61421         function continueTo(nextStep) {
61422             context.on('exit.intro', null);
61423             context.history().on('change.intro', null);
61424             select('.inspector-wrap').on('wheel.intro', null);
61425             nextStep();
61426         }
61427     }
61428
61429
61430     function closeTownHall() {
61431         if (!isTownHallSelected()) return clickTownHall();
61432
61433         var selector$$1 = '.entity-editor-pane button.preset-close svg use';
61434         var href = select(selector$$1).attr('href') || '#icon-close';
61435
61436         reveal('.entity-editor-pane',
61437             t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') })
61438         );
61439
61440         context.on('exit.intro', function() {
61441             continueTo(searchStreet);
61442         });
61443
61444         context.history().on('change.intro', function() {
61445             // update the close icon in the tooltip if the user edits something.
61446             var selector$$1 = '.entity-editor-pane button.preset-close svg use';
61447             var href = select(selector$$1).attr('href') || '#icon-close';
61448
61449             reveal('.entity-editor-pane',
61450                 t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }),
61451                 { duration: 0 }
61452             );
61453         });
61454
61455         function continueTo(nextStep) {
61456             context.on('exit.intro', null);
61457             context.history().on('change.intro', null);
61458             nextStep();
61459         }
61460     }
61461
61462
61463     function searchStreet() {
61464         context.enter(modeBrowse(context));
61465         context.history().reset('initial');  // ensure spring street exists
61466
61467         var msec = transitionTime(springStreet, context.map().center());
61468         if (msec) { reveal(null, null, { duration: 0 }); }
61469         context.map().zoom(19).centerEase(springStreet, msec);  // ..and user can see it
61470
61471         timeout(function() {
61472             reveal('.search-header input',
61473                 t('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') })
61474             );
61475
61476             select('.search-header input')
61477                 .on('keyup.intro', checkSearchResult);
61478         }, msec + 100);
61479     }
61480
61481
61482     function checkSearchResult() {
61483         var first = select('.feature-list-item:nth-child(0n+2)'),  // skip "No Results" item
61484             firstName = first.select('.entity-name'),
61485             name = t('intro.graph.name.spring-street');
61486
61487         if (!firstName.empty() && firstName.text() === name) {
61488             reveal(first.node(),
61489                 t('intro.navigation.choose_street', { name: name }),
61490                 { duration: 300 }
61491             );
61492
61493             context.on('exit.intro', function() {
61494                 continueTo(selectedStreet);
61495             });
61496
61497             select('.search-header input')
61498                 .on('keydown.intro', eventCancel, true)
61499                 .on('keyup.intro', null);
61500         }
61501
61502         function continueTo(nextStep) {
61503             context.on('exit.intro', null);
61504             select('.search-header input')
61505                 .on('keydown.intro', null)
61506                 .on('keyup.intro', null);
61507             nextStep();
61508         }
61509     }
61510
61511
61512     function selectedStreet() {
61513         if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
61514             return searchStreet();
61515         }
61516
61517         var onClick = function() { continueTo(editorStreet); };
61518         var entity = context.entity(springStreetEndId);
61519         var box = pointBox(entity.loc, context);
61520         box.height = 500;
61521
61522         reveal(box,
61523             t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
61524             { duration: 600, buttonText: t('intro.ok'), buttonCallback: onClick }
61525         );
61526
61527         timeout(function() {
61528             context.map().on('move.intro drawn.intro', function() {
61529                 var entity = context.hasEntity(springStreetEndId);
61530                 if (!entity) return;
61531                 var box = pointBox(entity.loc, context);
61532                 box.height = 500;
61533                 reveal(box,
61534                     t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
61535                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
61536                 );
61537             });
61538         }, 600);  // after reveal.
61539
61540         context.on('enter.intro', function(mode) {
61541             if (!context.hasEntity(springStreetId)) {
61542                 return continueTo(searchStreet);
61543             }
61544             var ids = context.selectedIDs();
61545             if (mode.id !== 'select' || !ids.length || ids[0] !== springStreetId) {
61546                 // keep Spring Street selected..
61547                 context.enter(modeSelect(context, [springStreetId]));
61548             }
61549         });
61550
61551         context.history().on('change.intro', function() {
61552             if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
61553                 timeout(function() {
61554                     continueTo(searchStreet);
61555                 }, 300);  // after any transition (e.g. if user deleted intersection)
61556             }
61557         });
61558
61559         function continueTo(nextStep) {
61560             context.map().on('move.intro drawn.intro', null);
61561             context.on('enter.intro', null);
61562             context.history().on('change.intro', null);
61563             nextStep();
61564         }
61565     }
61566
61567
61568     function editorStreet() {
61569         var selector$$1 = '.entity-editor-pane button.preset-close svg use';
61570         var href = select(selector$$1).attr('href') || '#icon-close';
61571
61572         reveal('.entity-editor-pane',
61573             t('intro.navigation.editor_street', {
61574                 button: icon(href, 'pre-text'),
61575                 field1: onewayField.label(),
61576                 field2: maxspeedField.label()
61577             })
61578         );
61579
61580         context.on('exit.intro', function() {
61581             continueTo(play);
61582         });
61583
61584         context.history().on('change.intro', function() {
61585             // update the close icon in the tooltip if the user edits something.
61586             var selector$$1 = '.entity-editor-pane button.preset-close svg use';
61587             var href = select(selector$$1).attr('href') || '#icon-close';
61588
61589             reveal('.entity-editor-pane',
61590                 t('intro.navigation.editor_street', {
61591                     button: icon(href, 'pre-text'),
61592                     field1: onewayField.label().toLowerCase(),
61593                     field2: maxspeedField.label().toLowerCase()
61594                 }), { duration: 0 }
61595             );
61596         });
61597
61598         function continueTo(nextStep) {
61599             context.on('exit.intro', null);
61600             context.history().on('change.intro', null);
61601             nextStep();
61602         }
61603     }
61604
61605
61606     function play() {
61607         dispatch$$1.call('done');
61608         reveal('#id-container',
61609             t('intro.navigation.play', { next: t('intro.points.title') }), {
61610                 tooltipBox: '.intro-nav-wrap .chapter-point',
61611                 buttonText: t('intro.ok'),
61612                 buttonCallback: function() { reveal('#id-container'); }
61613             }
61614         );
61615     }
61616
61617
61618     chapter.enter = function() {
61619         dragMap();
61620     };
61621
61622
61623     chapter.exit = function() {
61624         timeouts.forEach(window.clearTimeout);
61625         context.on('enter.intro exit.intro', null);
61626         context.map().on('move.intro drawn.intro', null);
61627         context.history().on('change.intro', null);
61628         select('.inspector-wrap').on('wheel.intro', null);
61629         select('.search-header input').on('keydown.intro keyup.intro', null);
61630     };
61631
61632
61633     chapter.restart = function() {
61634         chapter.exit();
61635         chapter.enter();
61636     };
61637
61638
61639     return utilRebind(chapter, dispatch$$1, 'on');
61640 }
61641
61642 function uiIntroPoint(context, reveal) {
61643     var dispatch$$1 = dispatch('done'),
61644         timeouts = [],
61645         intersection = [-85.63279, 41.94394],
61646         building = [-85.632422, 41.944045],
61647         cafePreset = context.presets().item('amenity/cafe'),
61648         pointId = null;
61649
61650
61651     var chapter = {
61652         title: 'intro.points.title'
61653     };
61654
61655
61656     function timeout(f, t$$1) {
61657         timeouts.push(window.setTimeout(f, t$$1));
61658     }
61659
61660
61661     function revealEditMenu(loc, text$$1, options) {
61662         var rect = context.surfaceRect();
61663         var point = context.curtainProjection(loc);
61664         var pad = 40;
61665         var width = 250 + (2 * pad);
61666         var height = 250;
61667         var startX = rect.left + point[0];
61668         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
61669         var box = {
61670             left: left,
61671             top: point[1] + rect.top - 60,
61672             width: width,
61673             height: height
61674         };
61675         reveal(box, text$$1, options);
61676     }
61677
61678
61679     function eventCancel() {
61680         event.stopPropagation();
61681         event.preventDefault();
61682     }
61683
61684
61685     function addPoint() {
61686         context.enter(modeBrowse(context));
61687         context.history().reset('initial');
61688
61689         var msec = transitionTime(intersection, context.map().center());
61690         if (msec) { reveal(null, null, { duration: 0 }); }
61691         context.map().zoom(19).centerEase(intersection, msec);
61692
61693         timeout(function() {
61694             var tooltip = reveal('button.add-point',
61695                 t('intro.points.add_point', { button: icon('#icon-point', 'pre-text') }));
61696
61697             pointId = null;
61698
61699             tooltip.selectAll('.tooltip-inner')
61700                 .insert('svg', 'span')
61701                 .attr('class', 'tooltip-illustration')
61702                 .append('use')
61703                 .attr('xlink:href', '#poi-images');
61704
61705             context.on('enter.intro', function(mode) {
61706                 if (mode.id !== 'add-point') return;
61707                 continueTo(placePoint);
61708             });
61709         }, msec + 100);
61710
61711         function continueTo(nextStep) {
61712             context.on('enter.intro', null);
61713             nextStep();
61714         }
61715     }
61716
61717
61718     function placePoint() {
61719         if (context.mode().id !== 'add-point') {
61720             return chapter.restart();
61721         }
61722
61723         var pointBox$$1 = pad$1(building, 150, context);
61724         reveal(pointBox$$1, t('intro.points.place_point'));
61725
61726         context.map().on('move.intro drawn.intro', function() {
61727             pointBox$$1 = pad$1(building, 150, context);
61728             reveal(pointBox$$1, t('intro.points.place_point'), { duration: 0 });
61729         });
61730
61731         context.on('enter.intro', function(mode) {
61732             if (mode.id !== 'select') return chapter.restart();
61733             pointId = context.mode().selectedIDs()[0];
61734             continueTo(searchPreset);
61735         });
61736
61737         function continueTo(nextStep) {
61738             context.map().on('move.intro drawn.intro', null);
61739             context.on('enter.intro', null);
61740             nextStep();
61741         }
61742     }
61743
61744
61745     function searchPreset() {
61746         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
61747             return addPoint();
61748         }
61749
61750         // disallow scrolling
61751         select('.inspector-wrap').on('wheel.intro', eventCancel);
61752
61753         select('.preset-search-input')
61754             .on('keydown.intro', null)
61755             .on('keyup.intro', checkPresetSearch);
61756
61757         reveal('.preset-search-input',
61758             t('intro.points.search_cafe', { preset: cafePreset.name() })
61759         );
61760
61761         context.on('enter.intro', function(mode) {
61762             if (!pointId || !context.hasEntity(pointId)) {
61763                 return continueTo(addPoint);
61764             }
61765
61766             var ids = context.selectedIDs();
61767             if (mode.id !== 'select' || !ids.length || ids[0] !== pointId) {
61768                 // keep the user's point selected..
61769                 context.enter(modeSelect(context, [pointId]));
61770
61771                 // disallow scrolling
61772                 select('.inspector-wrap').on('wheel.intro', eventCancel);
61773
61774                 select('.preset-search-input')
61775                     .on('keydown.intro', null)
61776                     .on('keyup.intro', checkPresetSearch);
61777
61778                 reveal('.preset-search-input',
61779                     t('intro.points.search_cafe', { preset: cafePreset.name() })
61780                 );
61781
61782                 context.history().on('change.intro', null);
61783             }
61784         });
61785
61786
61787         function checkPresetSearch() {
61788             var first = select('.preset-list-item:first-child');
61789
61790             if (first.classed('preset-amenity-cafe')) {
61791                 select('.preset-search-input')
61792                     .on('keydown.intro', eventCancel, true)
61793                     .on('keyup.intro', null);
61794
61795                 reveal(first.select('.preset-list-button').node(),
61796                     t('intro.points.choose_cafe', { preset: cafePreset.name() }),
61797                     { duration: 300 }
61798                 );
61799
61800                 context.history().on('change.intro', function() {
61801                     continueTo(aboutFeatureEditor);
61802                 });
61803             }
61804         }
61805
61806         function continueTo(nextStep) {
61807             context.on('enter.intro', null);
61808             context.history().on('change.intro', null);
61809             select('.inspector-wrap').on('wheel.intro', null);
61810             select('.preset-search-input').on('keydown.intro keyup.intro', null);
61811             nextStep();
61812         }
61813     }
61814
61815
61816     function aboutFeatureEditor() {
61817         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
61818             return addPoint();
61819         }
61820
61821         timeout(function() {
61822             reveal('.entity-editor-pane', t('intro.points.feature_editor'), {
61823                 tooltipClass: 'intro-points-describe',
61824                 buttonText: t('intro.ok'),
61825                 buttonCallback: function() { continueTo(addName); }
61826             });
61827         }, 400);
61828
61829         context.on('exit.intro', function() {
61830             // if user leaves select mode here, just continue with the tutorial.
61831             continueTo(reselectPoint);
61832         });
61833
61834         function continueTo(nextStep) {
61835             context.on('exit.intro', null);
61836             nextStep();
61837         }
61838     }
61839
61840
61841     function addName() {
61842         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
61843             return addPoint();
61844         }
61845
61846         // reset pane, in case user happened to change it..
61847         select('.inspector-wrap .panewrap').style('right', '0%');
61848
61849         timeout(function() {
61850             // It's possible for the user to add a name in a previous step..
61851             // If so, don't tell them to add the name in this step.
61852             // Give them an OK button instead.
61853             var entity = context.entity(pointId);
61854             if (entity.tags.name) {
61855                 var tooltip = reveal('.entity-editor-pane', t('intro.points.add_name'), {
61856                     tooltipClass: 'intro-points-describe',
61857                     buttonText: t('intro.ok'),
61858                     buttonCallback: function() { continueTo(addCloseEditor); }
61859                 });
61860                 tooltip.select('.instruction').style('display', 'none');
61861
61862             } else {
61863                 reveal('.entity-editor-pane', t('intro.points.add_name'),
61864                     { tooltipClass: 'intro-points-describe' }
61865                 );
61866             }
61867         }, 400);
61868
61869         context.history().on('change.intro', function() {
61870             continueTo(addCloseEditor);
61871         });
61872
61873         context.on('exit.intro', function() {
61874             // if user leaves select mode here, just continue with the tutorial.
61875             continueTo(reselectPoint);
61876         });
61877
61878         function continueTo(nextStep) {
61879             context.on('exit.intro', null);
61880             context.history().on('change.intro', null);
61881             nextStep();
61882         }
61883     }
61884
61885
61886     function addCloseEditor() {
61887         // reset pane, in case user happened to change it..
61888         select('.inspector-wrap .panewrap').style('right', '0%');
61889
61890         var selector$$1 = '.entity-editor-pane button.preset-close svg use';
61891         var href = select(selector$$1).attr('href') || '#icon-close';
61892
61893         context.on('exit.intro', function() {
61894             continueTo(reselectPoint);
61895         });
61896
61897         reveal('.entity-editor-pane',
61898             t('intro.points.add_close', { button: icon(href, 'pre-text') })
61899         );
61900
61901         function continueTo(nextStep) {
61902             context.on('exit.intro', null);
61903             nextStep();
61904         }
61905     }
61906
61907
61908     function reselectPoint() {
61909         if (!pointId) return chapter.restart();
61910         var entity = context.hasEntity(pointId);
61911         if (!entity) return chapter.restart();
61912
61913         // make sure it's still a cafe, in case user somehow changed it..
61914         var oldPreset = context.presets().match(entity, context.graph());
61915         context.replace(actionChangePreset(pointId, oldPreset, cafePreset));
61916
61917         context.enter(modeBrowse(context));
61918
61919         var msec = transitionTime(entity.loc, context.map().center());
61920         if (msec) { reveal(null, null, { duration: 0 }); }
61921         context.map().centerEase(entity.loc, msec);
61922
61923         timeout(function() {
61924             var box = pointBox(entity.loc, context);
61925             reveal(box, t('intro.points.reselect'), { duration: 600 });
61926
61927             timeout(function() {
61928                 context.map().on('move.intro drawn.intro', function() {
61929                     var entity = context.hasEntity(pointId);
61930                     if (!entity) return chapter.restart();
61931                     var box = pointBox(entity.loc, context);
61932                     reveal(box, t('intro.points.reselect'), { duration: 0 });
61933                 });
61934             }, 600); // after reveal..
61935
61936             context.on('enter.intro', function(mode) {
61937                 if (mode.id !== 'select') return;
61938                 continueTo(updatePoint);
61939             });
61940
61941         }, msec + 100);
61942
61943         function continueTo(nextStep) {
61944             context.map().on('move.intro drawn.intro', null);
61945             context.on('enter.intro', null);
61946             nextStep();
61947         }
61948     }
61949
61950
61951     function updatePoint() {
61952         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
61953             return continueTo(reselectPoint);
61954         }
61955
61956         // reset pane, in case user happened to untag the point..
61957         select('.inspector-wrap .panewrap').style('right', '0%');
61958
61959         context.on('exit.intro', function() {
61960             continueTo(reselectPoint);
61961         });
61962
61963         context.history().on('change.intro', function() {
61964             continueTo(updateCloseEditor);
61965         });
61966
61967         timeout(function() {
61968             reveal('.entity-editor-pane', t('intro.points.update'),
61969                 { tooltipClass: 'intro-points-describe' }
61970             );
61971         }, 400);
61972
61973         function continueTo(nextStep) {
61974             context.on('exit.intro', null);
61975             context.history().on('change.intro', null);
61976             nextStep();
61977         }
61978     }
61979
61980
61981     function updateCloseEditor() {
61982         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
61983             return continueTo(reselectPoint);
61984         }
61985
61986         // reset pane, in case user happened to change it..
61987         select('.inspector-wrap .panewrap').style('right', '0%');
61988
61989         context.on('exit.intro', function() {
61990             continueTo(rightClickPoint);
61991         });
61992
61993         timeout(function() {
61994             reveal('.entity-editor-pane',
61995                 t('intro.points.update_close', { button: icon('#icon-apply', 'pre-text') })
61996             );
61997         }, 500);
61998
61999         function continueTo(nextStep) {
62000             context.on('exit.intro', null);
62001             nextStep();
62002         }
62003     }
62004
62005
62006     function rightClickPoint() {
62007         if (!pointId) return chapter.restart();
62008         var entity = context.hasEntity(pointId);
62009         if (!entity) return chapter.restart();
62010
62011         context.enter(modeBrowse(context));
62012
62013         var box = pointBox(entity.loc, context);
62014         reveal(box, t('intro.points.rightclick'), { duration: 600 });
62015
62016         timeout(function() {
62017             context.map().on('move.intro drawn.intro', function() {
62018                 var entity = context.hasEntity(pointId);
62019                 if (!entity) return chapter.restart();
62020                 var box = pointBox(entity.loc, context);
62021                 reveal(box, t('intro.points.rightclick'), { duration: 0 });
62022             });
62023         }, 600); // after reveal
62024
62025         context.on('enter.intro', function(mode) {
62026             if (mode.id !== 'select') return;
62027             var ids = context.selectedIDs();
62028             if (ids.length !== 1 || ids[0] !== pointId) return;
62029
62030             timeout(function() {
62031                 var node = selectMenuItem('delete').node();
62032                 if (!node) return;
62033                 continueTo(enterDelete);
62034             }, 300);  // after menu visible
62035         });
62036
62037         function continueTo(nextStep) {
62038             context.on('enter.intro', null);
62039             context.map().on('move.intro drawn.intro', null);
62040             nextStep();
62041         }
62042     }
62043
62044
62045     function enterDelete() {
62046         if (!pointId) return chapter.restart();
62047         var entity = context.hasEntity(pointId);
62048         if (!entity) return chapter.restart();
62049
62050         var node = selectMenuItem('delete').node();
62051         if (!node) { return continueTo(rightClickPoint); }
62052
62053         revealEditMenu(entity.loc,
62054             t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') })
62055         );
62056
62057         timeout(function() {
62058             context.map().on('move.intro drawn.intro', function() {
62059                 revealEditMenu(entity.loc,
62060                     t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }),
62061                     { duration: 0}
62062                 );
62063             });
62064         }, 300); // after menu visible
62065
62066         context.on('exit.intro', function() {
62067             if (!pointId) return chapter.restart();
62068             var entity = context.hasEntity(pointId);
62069             if (entity) return continueTo(rightClickPoint);  // point still exists
62070         });
62071
62072         context.history().on('change.intro', function(changed) {
62073             if (changed.deleted().length) {
62074                 continueTo(undo);
62075             }
62076         });
62077
62078         function continueTo(nextStep) {
62079             context.map().on('move.intro drawn.intro', null);
62080             context.history().on('change.intro', null);
62081             context.on('exit.intro', null);
62082             nextStep();
62083         }
62084     }
62085
62086
62087     function undo() {
62088         context.history().on('change.intro', function() {
62089             continueTo(play);
62090         });
62091
62092         var iconName = '#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo');
62093         reveal('#bar button.undo-button',
62094             t('intro.points.undo', { button: icon(iconName, 'pre-text') })
62095         );
62096
62097         function continueTo(nextStep) {
62098             context.history().on('change.intro', null);
62099             nextStep();
62100         }
62101     }
62102
62103
62104     function play() {
62105         dispatch$$1.call('done');
62106         reveal('#id-container',
62107             t('intro.points.play', { next: t('intro.areas.title') }), {
62108                 tooltipBox: '.intro-nav-wrap .chapter-area',
62109                 buttonText: t('intro.ok'),
62110                 buttonCallback: function() { reveal('#id-container'); }
62111             }
62112         );
62113     }
62114
62115
62116     chapter.enter = function() {
62117         addPoint();
62118     };
62119
62120
62121     chapter.exit = function() {
62122         timeouts.forEach(window.clearTimeout);
62123         context.on('enter.intro exit.intro', null);
62124         context.map().on('move.intro drawn.intro', null);
62125         context.history().on('change.intro', null);
62126         select('.inspector-wrap').on('wheel.intro', eventCancel);
62127         select('.preset-search-input').on('keydown.intro keyup.intro', null);
62128     };
62129
62130
62131     chapter.restart = function() {
62132         chapter.exit();
62133         chapter.enter();
62134     };
62135
62136
62137     return utilRebind(chapter, dispatch$$1, 'on');
62138 }
62139
62140 function uiIntroArea(context, reveal) {
62141     var dispatch$$1 = dispatch('done'),
62142         playground = [-85.63552, 41.94159],
62143         playgroundPreset = context.presets().item('leisure/playground'),
62144         descriptionField = context.presets().field('description'),
62145         timeouts = [],
62146         areaId;
62147
62148
62149     var chapter = {
62150         title: 'intro.areas.title'
62151     };
62152
62153
62154     function timeout(f, t$$1) {
62155         timeouts.push(window.setTimeout(f, t$$1));
62156     }
62157
62158
62159     function eventCancel() {
62160         event.stopPropagation();
62161         event.preventDefault();
62162     }
62163
62164
62165     function revealPlayground(center, text$$1, options) {
62166         var padding = 180 * Math.pow(2, context.map().zoom() - 19.5);
62167         var box = pad$1(center, padding, context);
62168         reveal(box, text$$1, options);
62169     }
62170
62171
62172     function addArea() {
62173         context.enter(modeBrowse(context));
62174         context.history().reset('initial');
62175         areaId = null;
62176
62177         var msec = transitionTime(playground, context.map().center());
62178         if (msec) { reveal(null, null, { duration: 0 }); }
62179         context.map().zoom(19).centerEase(playground, msec);
62180
62181         timeout(function() {
62182             var tooltip = reveal('button.add-area',
62183                 t('intro.areas.add_playground', { button: icon('#icon-area', 'pre-text') }));
62184
62185             tooltip.selectAll('.tooltip-inner')
62186                 .insert('svg', 'span')
62187                 .attr('class', 'tooltip-illustration')
62188                 .append('use')
62189                 .attr('xlink:href', '#landuse-images');
62190
62191             context.on('enter.intro', function(mode) {
62192                 if (mode.id !== 'add-area') return;
62193                 continueTo(startPlayground);
62194             });
62195         }, msec + 100);
62196
62197         function continueTo(nextStep) {
62198             context.on('enter.intro', null);
62199             nextStep();
62200         }
62201     }
62202
62203
62204     function startPlayground() {
62205         if (context.mode().id !== 'add-area') {
62206             return chapter.restart();
62207         }
62208
62209         areaId = null;
62210         context.map().zoomEase(19.5, 500);
62211
62212         timeout(function() {
62213             revealPlayground(playground,
62214                 t('intro.areas.start_playground'), { duration: 250 }
62215             );
62216
62217             timeout(function() {
62218                 context.map().on('move.intro drawn.intro', function() {
62219                     revealPlayground(playground,
62220                         t('intro.areas.start_playground'), { duration: 0 }
62221                     );
62222                 });
62223                 context.on('enter.intro', function(mode) {
62224                     if (mode.id !== 'draw-area') return chapter.restart();
62225                     continueTo(continuePlayground);
62226                 });
62227             }, 250);  // after reveal
62228
62229         }, 550);  // after easing
62230
62231         function continueTo(nextStep) {
62232             context.map().on('move.intro drawn.intro', null);
62233             context.on('enter.intro', null);
62234             nextStep();
62235         }
62236     }
62237
62238
62239     function continuePlayground() {
62240         if (context.mode().id !== 'draw-area') {
62241             return chapter.restart();
62242         }
62243
62244         areaId = null;
62245         revealPlayground(playground,
62246             t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
62247             { duration: 250 }
62248         );
62249
62250         timeout(function() {
62251             context.map().on('move.intro drawn.intro', function() {
62252                 revealPlayground(playground,
62253                     t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
62254                     { duration: 0 }
62255                 );
62256             });
62257         }, 250);  // after reveal
62258
62259         context.on('enter.intro', function(mode) {
62260             if (mode.id === 'draw-area') {
62261                 var entity = context.hasEntity(context.selectedIDs()[0]);
62262                 if (entity && entity.nodes.length >= 6) {
62263                     return continueTo(finishPlayground);
62264                 } else {
62265                     return;
62266                 }
62267             } else if (mode.id === 'select') {
62268                 areaId = context.selectedIDs()[0];
62269                 return continueTo(searchPresets);
62270             } else {
62271                 return chapter.restart();
62272             }
62273         });
62274
62275         function continueTo(nextStep) {
62276             context.map().on('move.intro drawn.intro', null);
62277             context.on('enter.intro', null);
62278             nextStep();
62279         }
62280     }
62281
62282
62283     function finishPlayground() {
62284         if (context.mode().id !== 'draw-area') {
62285             return chapter.restart();
62286         }
62287
62288         areaId = null;
62289         revealPlayground(playground,
62290             t('intro.areas.finish_playground'), { duration: 250 }
62291         );
62292
62293         timeout(function() {
62294             context.map().on('move.intro drawn.intro', function() {
62295                 revealPlayground(playground,
62296                     t('intro.areas.finish_playground'), { duration: 0 }
62297                 );
62298             });
62299         }, 250);  // after reveal
62300
62301         context.on('enter.intro', function(mode) {
62302             if (mode.id === 'draw-area') {
62303                 return;
62304             } else if (mode.id === 'select') {
62305                 areaId = context.selectedIDs()[0];
62306                 return continueTo(searchPresets);
62307             } else {
62308                 return chapter.restart();
62309             }
62310         });
62311
62312         function continueTo(nextStep) {
62313             context.map().on('move.intro drawn.intro', null);
62314             context.on('enter.intro', null);
62315             nextStep();
62316         }
62317     }
62318
62319
62320     function searchPresets() {
62321         if (!areaId || !context.hasEntity(areaId)) {
62322             return addArea();
62323         }
62324         var ids = context.selectedIDs();
62325         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
62326             context.enter(modeSelect(context, [areaId]));
62327         }
62328
62329         // disallow scrolling
62330         select('.inspector-wrap').on('wheel.intro', eventCancel);
62331
62332         timeout(function() {
62333             // reset pane, in case user somehow happened to change it..
62334             select('.inspector-wrap .panewrap').style('right', '-100%');
62335
62336             select('.preset-search-input')
62337                 .on('keydown.intro', null)
62338                 .on('keyup.intro', checkPresetSearch);
62339
62340             reveal('.preset-search-input',
62341                 t('intro.areas.search_playground', { preset: playgroundPreset.name() })
62342             );
62343         }, 400);  // after preset list pane visible..
62344
62345         context.on('enter.intro', function(mode) {
62346             if (!areaId || !context.hasEntity(areaId)) {
62347                 return continueTo(addArea);
62348             }
62349
62350             var ids = context.selectedIDs();
62351             if (mode.id !== 'select' || !ids.length || ids[0] !== areaId) {
62352                 // keep the user's area selected..
62353                 context.enter(modeSelect(context, [areaId]));
62354
62355                 // reset pane, in case user somehow happened to change it..
62356                 select('.inspector-wrap .panewrap').style('right', '-100%');
62357                 // disallow scrolling
62358                 select('.inspector-wrap').on('wheel.intro', eventCancel);
62359
62360                 select('.preset-search-input')
62361                     .on('keydown.intro', null)
62362                     .on('keyup.intro', checkPresetSearch);
62363
62364                 reveal('.preset-search-input',
62365                     t('intro.areas.search_playground', { preset: playgroundPreset.name() })
62366                 );
62367
62368                 context.history().on('change.intro', null);
62369             }
62370         });
62371
62372         function checkPresetSearch() {
62373             var first = select('.preset-list-item:first-child');
62374
62375             if (first.classed('preset-leisure-playground')) {
62376                 reveal(first.select('.preset-list-button').node(),
62377                     t('intro.areas.choose_playground', { preset: playgroundPreset.name() }),
62378                     { duration: 300 }
62379                 );
62380
62381                 select('.preset-search-input')
62382                     .on('keydown.intro', eventCancel, true)
62383                     .on('keyup.intro', null);
62384
62385                 context.history().on('change.intro', function() {
62386                     continueTo(clickAddField);
62387                 });
62388             }
62389         }
62390
62391         function continueTo(nextStep) {
62392             select('.inspector-wrap').on('wheel.intro', null);
62393             context.on('enter.intro', null);
62394             context.history().on('change.intro', null);
62395             select('.preset-search-input').on('keydown.intro keyup.intro', null);
62396             nextStep();
62397         }
62398     }
62399
62400
62401     function clickAddField() {
62402         if (!areaId || !context.hasEntity(areaId)) {
62403             return addArea();
62404         }
62405         var ids = context.selectedIDs();
62406         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
62407             return searchPresets();
62408         }
62409
62410         if (!select('.form-field-description').empty()) {
62411             return continueTo(describePlayground);
62412         }
62413
62414         // disallow scrolling
62415         select('.inspector-wrap').on('wheel.intro', eventCancel);
62416
62417         timeout(function() {
62418             // reset pane, in case user somehow happened to change it..
62419             select('.inspector-wrap .panewrap').style('right', '0%');
62420
62421             // It's possible for the user to add a description in a previous step..
62422             // If they did this already, just continue to next step.
62423             var entity = context.entity(areaId);
62424             if (entity.tags.description) {
62425                 return continueTo(play);
62426             }
62427
62428             reveal('.more-fields .combobox-input',
62429                 t('intro.areas.add_field'),
62430                 { duration: 300 }
62431             );
62432
62433             select('.more-fields .combobox-input')
62434                 .on('click.intro', function() {
62435                     continueTo(chooseDescriptionField);
62436                 });
62437         }, 400);  // after editor pane visible
62438
62439         context.on('exit.intro', function() {
62440             return continueTo(searchPresets);
62441         });
62442
62443         function continueTo(nextStep) {
62444             select('.inspector-wrap').on('wheel.intro', null);
62445             select('.more-fields .combobox-input').on('click.intro', null);
62446             context.on('exit.intro', null);
62447             nextStep();
62448         }
62449     }
62450
62451
62452     function chooseDescriptionField() {
62453         if (!areaId || !context.hasEntity(areaId)) {
62454             return addArea();
62455         }
62456         var ids = context.selectedIDs();
62457         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
62458             return searchPresets();
62459         }
62460
62461         if (!select('.form-field-description').empty()) {
62462             return continueTo(describePlayground);
62463         }
62464
62465         // Make sure combobox is ready..
62466         if (select('div.combobox').empty()) {
62467             return continueTo(clickAddField);
62468         }
62469         // Watch for the combobox to go away..
62470         var watcher;
62471         watcher = window.setInterval(function() {
62472             if (select('div.combobox').empty()) {
62473                 window.clearInterval(watcher);
62474                 timeout(function() {
62475                     if (select('.form-field-description').empty()) {
62476                         continueTo(retryChooseDescription);
62477                     } else {
62478                         continueTo(describePlayground);
62479                     }
62480                 }, 300);  // after description field added.
62481             }
62482         }, 300);
62483
62484         reveal('div.combobox',
62485             t('intro.areas.choose_field', { field: descriptionField.label() }),
62486             { duration: 300 }
62487         );
62488
62489         context.on('exit.intro', function() {
62490             return continueTo(searchPresets);
62491         });
62492
62493         function continueTo(nextStep) {
62494             if (watcher) window.clearInterval(watcher);
62495             context.on('exit.intro', null);
62496             nextStep();
62497         }
62498     }
62499
62500
62501     function describePlayground() {
62502         if (!areaId || !context.hasEntity(areaId)) {
62503             return addArea();
62504         }
62505         var ids = context.selectedIDs();
62506         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
62507             return searchPresets();
62508         }
62509
62510         // reset pane, in case user happened to change it..
62511         select('.inspector-wrap .panewrap').style('right', '0%');
62512
62513         if (select('.form-field-description').empty()) {
62514             return continueTo(retryChooseDescription);
62515         }
62516
62517         context.on('exit.intro', function() {
62518             continueTo(play);
62519         });
62520
62521         reveal('.entity-editor-pane',
62522             t('intro.areas.describe_playground', { button: icon('#icon-apply', 'pre-text') }),
62523             { duration: 300 }
62524         );
62525
62526         function continueTo(nextStep) {
62527             context.on('exit.intro', null);
62528             nextStep();
62529         }
62530     }
62531
62532
62533     function retryChooseDescription() {
62534         if (!areaId || !context.hasEntity(areaId)) {
62535             return addArea();
62536         }
62537         var ids = context.selectedIDs();
62538         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
62539             return searchPresets();
62540         }
62541
62542         // reset pane, in case user happened to change it..
62543         select('.inspector-wrap .panewrap').style('right', '0%');
62544
62545         reveal('.entity-editor-pane',
62546             t('intro.areas.retry_add_field', { field: descriptionField.label() }), {
62547             buttonText: t('intro.ok'),
62548             buttonCallback: function() { continueTo(clickAddField); }
62549         });
62550
62551         context.on('exit.intro', function() {
62552             return continueTo(searchPresets);
62553         });
62554
62555         function continueTo(nextStep) {
62556             context.on('exit.intro', null);
62557             nextStep();
62558         }
62559     }
62560
62561
62562     function play() {
62563         dispatch$$1.call('done');
62564         reveal('#id-container',
62565             t('intro.areas.play', { next: t('intro.lines.title') }), {
62566                 tooltipBox: '.intro-nav-wrap .chapter-line',
62567                 buttonText: t('intro.ok'),
62568                 buttonCallback: function() { reveal('#id-container'); }
62569             }
62570         );
62571     }
62572
62573
62574     chapter.enter = function() {
62575         addArea();
62576     };
62577
62578
62579     chapter.exit = function() {
62580         timeouts.forEach(window.clearTimeout);
62581         context.on('enter.intro exit.intro', null);
62582         context.map().on('move.intro drawn.intro', null);
62583         context.history().on('change.intro', null);
62584         select('.inspector-wrap').on('wheel.intro', null);
62585         select('.preset-search-input').on('keydown.intro keyup.intro', null);
62586         select('.more-fields .combobox-input').on('click.intro', null);
62587     };
62588
62589
62590     chapter.restart = function() {
62591         chapter.exit();
62592         chapter.enter();
62593     };
62594
62595
62596     return utilRebind(chapter, dispatch$$1, 'on');
62597 }
62598
62599 function uiIntroLine(context, reveal) {
62600     var dispatch$$1 = dispatch('done'),
62601         timeouts = [],
62602         tulipRoadId = null,
62603         flowerRoadId = 'w646',
62604         tulipRoadStart = [-85.6297754121684, 41.95805253325314],
62605         tulipRoadMidpoint = [-85.62975395449628, 41.95787501510204],
62606         tulipRoadIntersection = [-85.62974496187628, 41.95742515554585],
62607         roadCategory = context.presets().item('category-road'),
62608         residentialPreset = context.presets().item('highway/residential'),
62609         woodRoadId = 'w525',
62610         woodRoadEndId = 'n2862',
62611         woodRoadAddNode = [-85.62390110349587, 41.95397111462291],
62612         woodRoadDragEndpoint = [-85.623867390213, 41.95466987786487],
62613         woodRoadDragMidpoint = [-85.62386254803509, 41.95430395953872],
62614         washingtonStreetId = 'w522',
62615         twelfthAvenueId = 'w1',
62616         eleventhAvenueEndId = 'n3550',
62617         twelfthAvenueEndId = 'n5',
62618         washingtonSegmentId = null,
62619         eleventhAvenueEnd = context.entity(eleventhAvenueEndId).loc,
62620         twelfthAvenueEnd = context.entity(twelfthAvenueEndId).loc,
62621         deleteLinesLoc = [-85.6219395542764, 41.95228033922477],
62622         twelfthAvenue = [-85.62219310052491, 41.952505413152956];
62623
62624
62625     var chapter = {
62626         title: 'intro.lines.title'
62627     };
62628
62629
62630     function timeout(f, t$$1) {
62631         timeouts.push(window.setTimeout(f, t$$1));
62632     }
62633
62634
62635     function eventCancel() {
62636         event.stopPropagation();
62637         event.preventDefault();
62638     }
62639
62640
62641     function revealEditMenu(loc, text$$1, options) {
62642         var rect = context.surfaceRect();
62643         var point = context.curtainProjection(loc);
62644         var pad = 40;
62645         var width = 250 + (2 * pad);
62646         var height = 350;
62647         var startX = rect.left + point[0];
62648         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
62649         var box = {
62650             left: left,
62651             top: point[1] + rect.top - 60,
62652             width: width,
62653             height: height
62654         };
62655         reveal(box, text$$1, options);
62656     }
62657
62658
62659     function addLine() {
62660         context.enter(modeBrowse(context));
62661         context.history().reset('initial');
62662
62663         var msec = transitionTime(tulipRoadStart, context.map().center());
62664         if (msec) { reveal(null, null, { duration: 0 }); }
62665         context.map().zoom(18.5).centerEase(tulipRoadStart, msec);
62666
62667         timeout(function() {
62668             var tooltip = reveal('button.add-line',
62669                 t('intro.lines.add_line', { button: icon('#icon-line', 'pre-text') }));
62670
62671             tooltip.selectAll('.tooltip-inner')
62672                 .insert('svg', 'span')
62673                 .attr('class', 'tooltip-illustration')
62674                 .append('use')
62675                 .attr('xlink:href', '#feature-images');
62676
62677             context.on('enter.intro', function(mode) {
62678                 if (mode.id !== 'add-line') return;
62679                 continueTo(startLine);
62680             });
62681         }, msec + 100);
62682
62683         function continueTo(nextStep) {
62684             context.on('enter.intro', null);
62685             nextStep();
62686         }
62687     }
62688
62689
62690     function startLine() {
62691         if (context.mode().id !== 'add-line') {
62692             return chapter.restart();
62693         }
62694
62695         tulipRoadId = null;
62696
62697         var padding = 70 * Math.pow(2, context.map().zoom() - 18);
62698         var box = pad$1(tulipRoadStart, padding, context);
62699         box.height = box.height + 100;
62700         reveal(box, t('intro.lines.start_line'));
62701
62702         context.map().on('move.intro drawn.intro', function() {
62703             padding = 70 * Math.pow(2, context.map().zoom() - 18);
62704             box = pad$1(tulipRoadStart, padding, context);
62705             box.height = box.height + 100;
62706             reveal(box, t('intro.lines.start_line'), { duration: 0 });
62707         });
62708
62709         context.on('enter.intro', function(mode) {
62710             if (mode.id !== 'draw-line') return chapter.restart();
62711             continueTo(drawLine);
62712         });
62713
62714         function continueTo(nextStep) {
62715             context.map().on('move.intro drawn.intro', null);
62716             context.on('enter.intro', null);
62717             nextStep();
62718         }
62719     }
62720
62721
62722     function drawLine() {
62723         if (context.mode().id !== 'draw-line') {
62724             return chapter.restart();
62725         }
62726
62727         tulipRoadId = context.mode().selectedIDs()[0];
62728         context.map().centerEase(tulipRoadMidpoint, 500);
62729
62730         timeout(function() {
62731             var padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
62732             var box = pad$1(tulipRoadMidpoint, padding, context);
62733             box.height = box.height * 2;
62734             reveal(box,
62735                 t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') })
62736             );
62737
62738             context.map().on('move.intro drawn.intro', function() {
62739                 padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
62740                 box = pad$1(tulipRoadMidpoint, padding, context);
62741                 box.height = box.height * 2;
62742                 reveal(box,
62743                     t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }),
62744                     { duration: 0 }
62745                 );
62746             });
62747         }, 550);  // after easing..
62748
62749         context.history().on('change.intro', function() {
62750             var entity = tulipRoadId && context.hasEntity(tulipRoadId);
62751             if (!entity) return chapter.restart();
62752
62753             if (isLineConnected()) {
62754                 continueTo(continueLine);
62755             }
62756         });
62757
62758         context.on('enter.intro', function(mode) {
62759             if (mode.id === 'draw-line')
62760                 return;
62761             else if (mode.id === 'select') {
62762                 continueTo(retryIntersect);
62763                 return;
62764             }
62765             else
62766                 return chapter.restart();
62767         });
62768
62769         function continueTo(nextStep) {
62770             context.map().on('move.intro drawn.intro', null);
62771             context.history().on('change.intro', null);
62772             context.on('enter.intro', null);
62773             nextStep();
62774         }
62775     }
62776
62777
62778     function isLineConnected() {
62779         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
62780         if (!entity) return false;
62781
62782         var drawNodes = context.graph().childNodes(entity);
62783         return lodash.some(drawNodes, function(node) {
62784             return lodash.some(context.graph().parentWays(node), function(parent) {
62785                 return parent.id === flowerRoadId;
62786             });
62787         });
62788     }
62789
62790
62791     function retryIntersect() {
62792         select(window).on('mousedown.intro', eventCancel, true);
62793
62794         var box = pad$1(tulipRoadIntersection, 80, context);
62795         reveal(box,
62796             t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') })
62797         );
62798
62799         timeout(chapter.restart, 3000);
62800     }
62801
62802
62803     function continueLine() {
62804         if (context.mode().id !== 'draw-line') return chapter.restart();
62805         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
62806         if (!entity) return chapter.restart();
62807
62808         context.map().centerEase(tulipRoadIntersection, 500);
62809
62810         reveal('#surface', t('intro.lines.continue_line'));
62811
62812         context.on('enter.intro', function(mode) {
62813             if (mode.id === 'draw-line')
62814                 return;
62815             else if (mode.id === 'select')
62816                 return continueTo(chooseCategoryRoad);
62817             else
62818                 return chapter.restart();
62819         });
62820
62821         function continueTo(nextStep) {
62822             context.on('enter.intro', null);
62823             nextStep();
62824         }
62825     }
62826
62827
62828     function chooseCategoryRoad() {
62829         if (context.mode().id !== 'select') {
62830             return chapter.restart();
62831         }
62832
62833         context.on('exit.intro', function() {
62834             return chapter.restart();
62835         });
62836
62837         var button = select('.preset-category-road .preset-list-button');
62838         if (button.empty()) return chapter.restart();
62839
62840         // disallow scrolling
62841         select('.inspector-wrap').on('wheel.intro', eventCancel);
62842
62843         timeout(function() {
62844             // reset pane, in case user somehow happened to change it..
62845             select('.inspector-wrap .panewrap').style('right', '-100%');
62846
62847             reveal(button.node(),
62848                 t('intro.lines.choose_category_road', { category: roadCategory.name() })
62849             );
62850
62851             button.on('click.intro', function() {
62852                 continueTo(choosePresetResidential);
62853             });
62854
62855         }, 400);  // after editor pane visible
62856
62857         function continueTo(nextStep) {
62858             select('.inspector-wrap').on('wheel.intro', null);
62859             select('.preset-list-button').on('click.intro', null);
62860             context.on('exit.intro', null);
62861             nextStep();
62862         }
62863     }
62864
62865
62866     function choosePresetResidential() {
62867         if (context.mode().id !== 'select') {
62868             return chapter.restart();
62869         }
62870
62871         context.on('exit.intro', function() {
62872             return chapter.restart();
62873         });
62874
62875         var subgrid = select('.preset-category-road .subgrid');
62876         if (subgrid.empty()) return chapter.restart();
62877
62878         subgrid.selectAll(':not(.preset-highway-residential) .preset-list-button')
62879             .on('click.intro', function() {
62880                 continueTo(retryPresetResidential);
62881             });
62882
62883         subgrid.selectAll('.preset-highway-residential .preset-list-button')
62884             .on('click.intro', function() {
62885                 continueTo(nameRoad);
62886             });
62887
62888         timeout(function() {
62889             reveal(subgrid.node(),
62890                 t('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }),
62891                 { tooltipBox: '.preset-highway-residential .preset-list-button', duration: 300 }
62892             );
62893         }, 300);
62894
62895         function continueTo(nextStep) {
62896             select('.preset-list-button').on('click.intro', null);
62897             context.on('exit.intro', null);
62898             nextStep();
62899         }
62900     }
62901
62902
62903     // selected wrong road type
62904     function retryPresetResidential() {
62905         if (context.mode().id !== 'select') {
62906             return chapter.restart();
62907         }
62908
62909         context.on('exit.intro', function() {
62910             return chapter.restart();
62911         });
62912
62913         // disallow scrolling
62914         select('.inspector-wrap').on('wheel.intro', eventCancel);
62915
62916         timeout(function() {
62917             var button = select('.entity-editor-pane .preset-list-button');
62918
62919             reveal(button.node(),
62920                 t('intro.lines.retry_preset_residential', { preset: residentialPreset.name() })
62921             );
62922
62923             button.on('click.intro', function() {
62924                 continueTo(chooseCategoryRoad);
62925             });
62926
62927         }, 500);
62928
62929         function continueTo(nextStep) {
62930             select('.inspector-wrap').on('wheel.intro', null);
62931             select('.preset-list-button').on('click.intro', null);
62932             context.on('exit.intro', null);
62933             nextStep();
62934         }
62935     }
62936
62937
62938     function nameRoad() {
62939         context.on('exit.intro', function() {
62940             continueTo(didNameRoad);
62941         });
62942
62943         timeout(function() {
62944             reveal('.entity-editor-pane',
62945                 t('intro.lines.name_road', { button: icon('#icon-apply', 'pre-text') }),
62946                 { tooltipClass: 'intro-lines-name_road' }
62947             );
62948         }, 500);
62949
62950         function continueTo(nextStep) {
62951             context.on('exit.intro', null);
62952             nextStep();
62953         }
62954     }
62955
62956
62957     function didNameRoad() {
62958         context.history().checkpoint('doneAddLine');
62959
62960         timeout(function() {
62961             reveal('#surface', t('intro.lines.did_name_road'), {
62962                 buttonText: t('intro.ok'),
62963                 buttonCallback: function() { continueTo(updateLine); }
62964             });
62965         }, 500);
62966
62967         function continueTo(nextStep) {
62968             nextStep();
62969         }
62970     }
62971
62972
62973     function updateLine() {
62974         context.history().reset('doneAddLine');
62975         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
62976             return chapter.restart();
62977         }
62978
62979         var msec = transitionTime(woodRoadDragMidpoint, context.map().center());
62980         if (msec) { reveal(null, null, { duration: 0 }); }
62981         context.map().zoom(19).centerEase(woodRoadDragMidpoint, msec);
62982
62983         timeout(function() {
62984             var padding = 250 * Math.pow(2, context.map().zoom() - 19);
62985             var box = pad$1(woodRoadDragMidpoint, padding, context);
62986             var advance = function() { continueTo(addNode); };
62987
62988             reveal(box, t('intro.lines.update_line'),
62989                 { buttonText: t('intro.ok'), buttonCallback: advance }
62990             );
62991
62992             context.map().on('move.intro drawn.intro', function() {
62993                 var padding = 250 * Math.pow(2, context.map().zoom() - 19);
62994                 var box = pad$1(woodRoadDragMidpoint, padding, context);
62995                 reveal(box, t('intro.lines.update_line'),
62996                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
62997                 );
62998             });
62999         }, msec + 100);
63000
63001         function continueTo(nextStep) {
63002             context.map().on('move.intro drawn.intro', null);
63003             nextStep();
63004         }
63005     }
63006
63007
63008     function addNode() {
63009         context.history().reset('doneAddLine');
63010         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63011             return chapter.restart();
63012         }
63013
63014         var padding = 40 * Math.pow(2, context.map().zoom() - 19);
63015         var box = pad$1(woodRoadAddNode, padding, context);
63016         reveal(box, t('intro.lines.add_node'));
63017
63018         context.map().on('move.intro drawn.intro', function() {
63019             var padding = 40 * Math.pow(2, context.map().zoom() - 19);
63020             var box = pad$1(woodRoadAddNode, padding, context);
63021             reveal(box, t('intro.lines.add_node'), { duration: 0 });
63022         });
63023
63024         context.history().on('change.intro', function(changed) {
63025             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63026                 return continueTo(updateLine);
63027             }
63028             if (changed.created().length === 1) {
63029                 timeout(function() { continueTo(startDragEndpoint); }, 500);
63030             }
63031         });
63032
63033         context.on('enter.intro', function(mode) {
63034             if (mode.id !== 'select') {
63035                 continueTo(updateLine);
63036             }
63037         });
63038
63039         function continueTo(nextStep) {
63040             context.map().on('move.intro drawn.intro', null);
63041             context.history().on('change.intro', null);
63042             context.on('enter.intro', null);
63043             nextStep();
63044         }
63045     }
63046
63047
63048     function startDragEndpoint() {
63049         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63050             return continueTo(updateLine);
63051         }
63052         if (context.selectedIDs().indexOf(woodRoadId) === -1) {
63053             context.enter(modeSelect(context, [woodRoadId]));
63054         }
63055
63056         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
63057         var box = pad$1(woodRoadDragEndpoint, padding, context);
63058         reveal(box, t('intro.lines.start_drag_endpoint'));
63059
63060         context.map().on('move.intro drawn.intro', function() {
63061             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63062                 return continueTo(updateLine);
63063             }
63064             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
63065             var box = pad$1(woodRoadDragEndpoint, padding, context);
63066             reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 });
63067
63068             var entity = context.entity(woodRoadEndId);
63069             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) {
63070                 continueTo(finishDragEndpoint);
63071             }
63072         });
63073
63074         context.on('enter.intro', function(mode) {
63075             if (mode.id !== 'select') {
63076                 // keep Wood Road selected so endpoint stays draggable..
63077                 context.enter(modeSelect(context, [woodRoadId]));
63078             }
63079         });
63080
63081         function continueTo(nextStep) {
63082             context.map().on('move.intro drawn.intro', null);
63083             context.on('enter.intro', null);
63084             nextStep();
63085         }
63086     }
63087
63088
63089     function finishDragEndpoint() {
63090         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63091             return continueTo(updateLine);
63092         }
63093
63094         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
63095         var box = pad$1(woodRoadDragEndpoint, padding, context);
63096         reveal(box, t('intro.lines.finish_drag_endpoint'));
63097
63098         context.map().on('move.intro drawn.intro', function() {
63099             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63100                 return continueTo(updateLine);
63101             }
63102             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
63103             var box = pad$1(woodRoadDragEndpoint, padding, context);
63104             reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 });
63105
63106             var entity = context.entity(woodRoadEndId);
63107             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) {
63108                 continueTo(startDragEndpoint);
63109             }
63110         });
63111
63112         context.on('enter.intro', function() {
63113             continueTo(startDragMidpoint);
63114         });
63115
63116         function continueTo(nextStep) {
63117             context.map().on('move.intro drawn.intro', null);
63118             context.on('enter.intro', null);
63119             nextStep();
63120         }
63121     }
63122
63123
63124     function startDragMidpoint() {
63125         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63126             return continueTo(updateLine);
63127         }
63128         if (context.selectedIDs().indexOf(woodRoadId) === -1) {
63129             context.enter(modeSelect(context, [woodRoadId]));
63130         }
63131
63132         var padding = 80 * Math.pow(2, context.map().zoom() - 19);
63133         var box = pad$1(woodRoadDragMidpoint, padding, context);
63134         reveal(box, t('intro.lines.start_drag_midpoint'));
63135
63136         context.map().on('move.intro drawn.intro', function() {
63137             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63138                 return continueTo(updateLine);
63139             }
63140             var padding = 80 * Math.pow(2, context.map().zoom() - 19);
63141             var box = pad$1(woodRoadDragMidpoint, padding, context);
63142             reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 });
63143         });
63144
63145         context.history().on('change.intro', function(changed) {
63146             if (changed.created().length === 1) {
63147                 continueTo(continueDragMidpoint);
63148             }
63149         });
63150
63151         context.on('enter.intro', function(mode) {
63152             if (mode.id !== 'select') {
63153                 // keep Wood Road selected so midpoint triangles are drawn..
63154                 context.enter(modeSelect(context, [woodRoadId]));
63155             }
63156         });
63157
63158         function continueTo(nextStep) {
63159             context.map().on('move.intro drawn.intro', null);
63160             context.history().on('change.intro', null);
63161             context.on('enter.intro', null);
63162             nextStep();
63163         }
63164     }
63165
63166
63167     function continueDragMidpoint() {
63168         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63169             return continueTo(updateLine);
63170         }
63171
63172         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
63173         var box = pad$1(woodRoadDragEndpoint, padding, context);
63174         box.height += 400;
63175
63176         var advance = function() {
63177             context.history().checkpoint('doneUpdateLine');
63178             continueTo(deleteLines);
63179         };
63180
63181         reveal(box, t('intro.lines.continue_drag_midpoint'),
63182             { buttonText: t('intro.ok'), buttonCallback: advance }
63183         );
63184
63185         context.map().on('move.intro drawn.intro', function() {
63186             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
63187                 return continueTo(updateLine);
63188             }
63189             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
63190             var box = pad$1(woodRoadDragEndpoint, padding, context);
63191             box.height += 400;
63192             reveal(box, t('intro.lines.continue_drag_midpoint'),
63193                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
63194             );
63195         });
63196
63197         function continueTo(nextStep) {
63198             context.map().on('move.intro drawn.intro', null);
63199             nextStep();
63200         }
63201     }
63202
63203
63204     function deleteLines() {
63205         context.history().reset('doneUpdateLine');
63206         context.enter(modeBrowse(context));
63207
63208         if (!context.hasEntity(washingtonStreetId) ||
63209             !context.hasEntity(twelfthAvenueId) ||
63210             !context.hasEntity(eleventhAvenueEndId)) {
63211             return chapter.restart();
63212         }
63213
63214         var msec = transitionTime(deleteLinesLoc, context.map().center());
63215         if (msec) { reveal(null, null, { duration: 0 }); }
63216         context.map().zoom(18).centerEase(deleteLinesLoc, msec);
63217
63218         timeout(function() {
63219             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63220             var box = pad$1(deleteLinesLoc, padding, context);
63221             box.top -= 200;
63222             box.height += 400;
63223             var advance = function() { continueTo(rightClickIntersection); };
63224
63225             reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
63226                 { buttonText: t('intro.ok'), buttonCallback: advance }
63227             );
63228
63229             context.map().on('move.intro drawn.intro', function() {
63230                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63231                 var box = pad$1(deleteLinesLoc, padding, context);
63232                 box.top -= 200;
63233                 box.height += 400;
63234                 reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
63235                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
63236                 );
63237             });
63238
63239             context.history().on('change.intro', function() {
63240                 timeout(function() {
63241                     continueTo(deleteLines);
63242                 }, 500);  // after any transition (e.g. if user deleted intersection)
63243             });
63244
63245         }, msec + 100);
63246
63247         function continueTo(nextStep) {
63248             context.map().on('move.intro drawn.intro', null);
63249             context.history().on('change.intro', null);
63250             nextStep();
63251         }
63252     }
63253
63254
63255     function rightClickIntersection() {
63256         context.history().reset('doneUpdateLine');
63257         context.enter(modeBrowse(context));
63258
63259         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
63260
63261         timeout(function() {
63262             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
63263             var box = pad$1(eleventhAvenueEnd, padding, context);
63264             reveal(box, t('intro.lines.rightclick_intersection',
63265                 { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') })
63266             );
63267
63268             context.map().on('move.intro drawn.intro', function() {
63269                 var padding = 60 * Math.pow(2, context.map().zoom() - 18);
63270                 var box = pad$1(eleventhAvenueEnd, padding, context);
63271                 reveal(box, t('intro.lines.rightclick_intersection',
63272                     { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }),
63273                     { duration: 0 }
63274                 );
63275             });
63276
63277             context.on('enter.intro', function(mode) {
63278                 if (mode.id !== 'select') return;
63279                 var ids = context.selectedIDs();
63280                 if (ids.length !== 1 || ids[0] !== eleventhAvenueEndId) return;
63281
63282                 timeout(function() {
63283                     var node = selectMenuItem('split').node();
63284                     if (!node) return;
63285                     continueTo(splitIntersection);
63286                 }, 300);  // after menu visible
63287             });
63288
63289             context.history().on('change.intro', function() {
63290                 timeout(function() {
63291                     continueTo(deleteLines);
63292                 }, 300);  // after any transition (e.g. if user deleted intersection)
63293             });
63294
63295         }, 600);
63296
63297         function continueTo(nextStep) {
63298             context.map().on('move.intro drawn.intro', null);
63299             context.on('enter.intro', null);
63300             context.history().on('change.intro', null);
63301             nextStep();
63302         }
63303     }
63304
63305
63306     function splitIntersection() {
63307         if (!context.hasEntity(washingtonStreetId) ||
63308             !context.hasEntity(twelfthAvenueId) ||
63309             !context.hasEntity(eleventhAvenueEndId)) {
63310             return continueTo(deleteLines);
63311         }
63312
63313         var node = selectMenuItem('split').node();
63314         if (!node) { return continueTo(rightClickIntersection); }
63315
63316         var wasChanged = false;
63317         var menuCoords = context.map().mouseCoordinates();
63318         washingtonSegmentId = null;
63319
63320         revealEditMenu(menuCoords, t('intro.lines.split_intersection',
63321             { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') })
63322         );
63323
63324         context.map().on('move.intro drawn.intro', function() {
63325             var node = selectMenuItem('split').node();
63326             if (!wasChanged && !node) { return continueTo(rightClickIntersection); }
63327
63328             revealEditMenu(menuCoords, t('intro.lines.split_intersection',
63329                 { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }),
63330                 { duration: 0 }
63331             );
63332         });
63333
63334         context.history().on('change.intro', function(changed) {
63335             wasChanged = true;
63336             timeout(function() {
63337                 if (context.history().undoAnnotation() === t('operations.split.annotation.line')) {
63338                     washingtonSegmentId = changed.created()[0].id;
63339                     continueTo(didSplit);
63340                 } else {
63341                     washingtonSegmentId = null;
63342                     continueTo(retrySplit);
63343                 }
63344             }, 300);  // after any transition (e.g. if user deleted intersection)
63345         });
63346
63347         function continueTo(nextStep) {
63348             context.map().on('move.intro drawn.intro', null);
63349             context.history().on('change.intro', null);
63350             nextStep();
63351         }
63352     }
63353
63354
63355     function retrySplit() {
63356         context.enter(modeBrowse(context));
63357         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
63358         var advance = function() { continueTo(rightClickIntersection); };
63359
63360         var padding = 60 * Math.pow(2, context.map().zoom() - 18);
63361         var box = pad$1(eleventhAvenueEnd, padding, context);
63362         reveal(box, t('intro.lines.retry_split'),
63363             { buttonText: t('intro.ok'), buttonCallback: advance }
63364         );
63365
63366         context.map().on('move.intro drawn.intro', function() {
63367             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
63368             var box = pad$1(eleventhAvenueEnd, padding, context);
63369             reveal(box, t('intro.lines.retry_split'),
63370                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
63371             );
63372         });
63373
63374         function continueTo(nextStep) {
63375             context.map().on('move.intro drawn.intro', null);
63376             nextStep();
63377         }
63378     }
63379
63380
63381     function didSplit() {
63382         if (!washingtonSegmentId ||
63383             !context.hasEntity(washingtonSegmentId) ||
63384             !context.hasEntity(washingtonStreetId) ||
63385             !context.hasEntity(twelfthAvenueId) ||
63386             !context.hasEntity(eleventhAvenueEndId)) {
63387             return continueTo(rightClickIntersection);
63388         }
63389
63390         var ids = context.selectedIDs();
63391         var string = 'intro.lines.did_split_' + (ids.length > 1 ? 'multi' : 'single');
63392         var street = t('intro.graph.name.washington-street');
63393
63394         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63395         var box = pad$1(twelfthAvenue, padding, context);
63396         box.width = box.width / 2;
63397         reveal(box, t(string, { street1: street, street2: street }),
63398             { duration: 500 }
63399         );
63400
63401         timeout(function() {
63402             context.map().zoom(18).centerEase(twelfthAvenue, 500);
63403
63404             context.map().on('move.intro drawn.intro', function() {
63405                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63406                 var box = pad$1(twelfthAvenue, padding, context);
63407                 box.width = box.width / 2;
63408                 reveal(box, t(string, { street1: street, street2: street }),
63409                     { duration: 0 }
63410                 );
63411             });
63412         }, 600);  // after initial reveal and curtain cut
63413
63414         context.on('enter.intro', function() {
63415             var ids = context.selectedIDs();
63416             if (ids.length === 1 && ids[0] === washingtonSegmentId) {
63417                 continueTo(multiSelect);
63418             }
63419         });
63420
63421         context.history().on('change.intro', function() {
63422             if (!washingtonSegmentId ||
63423                 !context.hasEntity(washingtonSegmentId) ||
63424                 !context.hasEntity(washingtonStreetId) ||
63425                 !context.hasEntity(twelfthAvenueId) ||
63426                 !context.hasEntity(eleventhAvenueEndId)) {
63427                 return continueTo(rightClickIntersection);
63428             }
63429         });
63430
63431         function continueTo(nextStep) {
63432             context.map().on('move.intro drawn.intro', null);
63433             context.on('enter.intro', null);
63434             context.history().on('change.intro', null);
63435             nextStep();
63436         }
63437     }
63438
63439
63440     function multiSelect() {
63441         if (!washingtonSegmentId ||
63442             !context.hasEntity(washingtonSegmentId) ||
63443             !context.hasEntity(washingtonStreetId) ||
63444             !context.hasEntity(twelfthAvenueId) ||
63445             !context.hasEntity(eleventhAvenueEndId)) {
63446             return continueTo(rightClickIntersection);
63447         }
63448
63449         var ids = context.selectedIDs();
63450         var hasWashington = ids.indexOf(washingtonSegmentId) !== -1;
63451         var hasTwelfth = ids.indexOf(twelfthAvenueId) !== -1;
63452
63453         if (hasWashington && hasTwelfth) {
63454             return continueTo(multiRightClick);
63455         } else if (!hasWashington && !hasTwelfth) {
63456             return continueTo(didSplit);
63457         }
63458
63459         context.map().zoom(18).centerEase(twelfthAvenue, 500);
63460
63461         timeout(function() {
63462             var selected, other, padding, box;
63463             if (hasWashington) {
63464                 selected = t('intro.graph.name.washington-street');
63465                 other = t('intro.graph.name.12th-avenue');
63466                 padding = 60 * Math.pow(2, context.map().zoom() - 18);
63467                 box = pad$1(twelfthAvenueEnd, padding, context);
63468                 box.width *= 3;
63469             } else {
63470                 selected = t('intro.graph.name.12th-avenue');
63471                 other = t('intro.graph.name.washington-street');
63472                 padding = 200 * Math.pow(2, context.map().zoom() - 18);
63473                 box = pad$1(twelfthAvenue, padding, context);
63474                 box.width /= 2;
63475             }
63476
63477             reveal(box,
63478                 t('intro.lines.multi_select', { selected: selected, other1: other, other2: other })
63479             );
63480
63481             context.map().on('move.intro drawn.intro', function() {
63482                 if (hasWashington) {
63483                     selected = t('intro.graph.name.washington-street');
63484                     other = t('intro.graph.name.12th-avenue');
63485                     padding = 60 * Math.pow(2, context.map().zoom() - 18);
63486                     box = pad$1(twelfthAvenueEnd, padding, context);
63487                     box.width *= 3;
63488                 } else {
63489                     selected = t('intro.graph.name.12th-avenue');
63490                     other = t('intro.graph.name.washington-street');
63491                     padding = 200 * Math.pow(2, context.map().zoom() - 18);
63492                     box = pad$1(twelfthAvenue, padding, context);
63493                     box.width /= 2;
63494                 }
63495
63496                 reveal(box,
63497                     t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }),
63498                     { duration: 0 }
63499                 );
63500             });
63501
63502             context.on('enter.intro', function() {
63503                 continueTo(multiSelect);
63504             });
63505
63506             context.history().on('change.intro', function() {
63507                 if (!washingtonSegmentId ||
63508                     !context.hasEntity(washingtonSegmentId) ||
63509                     !context.hasEntity(washingtonStreetId) ||
63510                     !context.hasEntity(twelfthAvenueId) ||
63511                     !context.hasEntity(eleventhAvenueEndId)) {
63512                     return continueTo(rightClickIntersection);
63513                 }
63514             });
63515         }, 600);
63516
63517         function continueTo(nextStep) {
63518             context.map().on('move.intro drawn.intro', null);
63519             context.on('enter.intro', null);
63520             context.history().on('change.intro', null);
63521             nextStep();
63522         }
63523     }
63524
63525
63526     function multiRightClick() {
63527         if (!washingtonSegmentId ||
63528             !context.hasEntity(washingtonSegmentId) ||
63529             !context.hasEntity(washingtonStreetId) ||
63530             !context.hasEntity(twelfthAvenueId) ||
63531             !context.hasEntity(eleventhAvenueEndId)) {
63532             return continueTo(rightClickIntersection);
63533         }
63534
63535         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63536         var box = pad$1(twelfthAvenue, padding, context);
63537         reveal(box, t('intro.lines.multi_rightclick'));
63538
63539         context.map().on('move.intro drawn.intro', function() {
63540             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63541             var box = pad$1(twelfthAvenue, padding, context);
63542             reveal(box, t('intro.lines.multi_rightclick'), { duration: 0 });
63543         });
63544
63545         select(window).on('click.intro contextmenu.intro', function() {
63546             timeout(function() {
63547                 var ids = context.selectedIDs();
63548                 if (ids.length === 2 &&
63549                     ids.indexOf(twelfthAvenueId) !== -1 &&
63550                     ids.indexOf(washingtonSegmentId) !== -1) {
63551                         var node = selectMenuItem('delete').node();
63552                         if (!node) return;
63553                         continueTo(multiDelete);
63554                 } else if (ids.length === 1 &&
63555                     ids.indexOf(washingtonSegmentId) !== -1) {
63556                     return continueTo(multiSelect);
63557                 } else {
63558                     return continueTo(didSplit);
63559                 }
63560             }, 300);  // after edit menu visible
63561         }, true);
63562
63563         context.history().on('change.intro', function() {
63564             if (!washingtonSegmentId ||
63565                 !context.hasEntity(washingtonSegmentId) ||
63566                 !context.hasEntity(washingtonStreetId) ||
63567                 !context.hasEntity(twelfthAvenueId) ||
63568                 !context.hasEntity(eleventhAvenueEndId)) {
63569                 return continueTo(rightClickIntersection);
63570             }
63571         });
63572
63573         function continueTo(nextStep) {
63574             context.map().on('move.intro drawn.intro', null);
63575             select(window).on('click.intro contextmenu.intro', null, true);
63576             context.history().on('change.intro', null);
63577             nextStep();
63578         }
63579     }
63580
63581
63582     function multiDelete() {
63583         if (!washingtonSegmentId ||
63584             !context.hasEntity(washingtonSegmentId) ||
63585             !context.hasEntity(washingtonStreetId) ||
63586             !context.hasEntity(twelfthAvenueId) ||
63587             !context.hasEntity(eleventhAvenueEndId)) {
63588             return continueTo(rightClickIntersection);
63589         }
63590
63591         var node = selectMenuItem('delete').node();
63592         if (!node) return continueTo(multiRightClick);
63593
63594         var menuCoords = context.map().mouseCoordinates();
63595         revealEditMenu(menuCoords,
63596             t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') })
63597         );
63598
63599         context.map().on('move.intro drawn.intro', function() {
63600             revealEditMenu(menuCoords,
63601                 t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') }),
63602                 { duration: 0 }
63603             );
63604         });
63605
63606         context.on('exit.intro', function() {
63607             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
63608                 return continueTo(multiSelect);  // left select mode but roads still exist
63609             }
63610         });
63611
63612         context.history().on('change.intro', function() {
63613             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
63614                 continueTo(retryDelete);         // changed something but roads still exist
63615             } else {
63616                 continueTo(play);
63617             }
63618         });
63619
63620         function continueTo(nextStep) {
63621             context.map().on('move.intro drawn.intro', null);
63622             context.on('exit.intro', null);
63623             context.history().on('change.intro', null);
63624             nextStep();
63625         }
63626     }
63627
63628
63629     function retryDelete() {
63630         context.enter(modeBrowse(context));
63631
63632         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
63633         var box = pad$1(twelfthAvenue, padding, context);
63634         reveal(box, t('intro.lines.retry_delete'), {
63635             buttonText: t('intro.ok'),
63636             buttonCallback: function() { continueTo(multiSelect); }
63637         });
63638
63639         function continueTo(nextStep) {
63640             nextStep();
63641         }
63642     }
63643
63644
63645     function play() {
63646         dispatch$$1.call('done');
63647         reveal('#id-container',
63648             t('intro.lines.play', { next: t('intro.buildings.title') }), {
63649                 tooltipBox: '.intro-nav-wrap .chapter-building',
63650                 buttonText: t('intro.ok'),
63651                 buttonCallback: function() { reveal('#id-container'); }
63652             }
63653         );
63654    }
63655
63656
63657     chapter.enter = function() {
63658         addLine();
63659     };
63660
63661
63662     chapter.exit = function() {
63663         timeouts.forEach(window.clearTimeout);
63664         select(window).on('mousedown.intro', null, true);
63665         context.on('enter.intro exit.intro', null);
63666         context.map().on('move.intro drawn.intro', null);
63667         context.history().on('change.intro', null);
63668         select('.inspector-wrap').on('wheel.intro', null);
63669         select('.preset-list-button').on('click.intro', null);
63670     };
63671
63672
63673     chapter.restart = function() {
63674         chapter.exit();
63675         chapter.enter();
63676     };
63677
63678
63679     return utilRebind(chapter, dispatch$$1, 'on');
63680 }
63681
63682 function uiIntroBuilding(context, reveal) {
63683     var dispatch$$1 = dispatch('done'),
63684         house = [-85.62815, 41.95638],
63685         tank = [-85.62732, 41.95347],
63686         buildingCatetory = context.presets().item('category-building'),
63687         housePreset = context.presets().item('building/house'),
63688         tankPreset = context.presets().item('man_made/storage_tank'),
63689         timeouts = [],
63690         houseId = null,
63691         tankId = null;
63692
63693
63694     var chapter = {
63695         title: 'intro.buildings.title'
63696     };
63697
63698
63699     function timeout(f, t$$1) {
63700         timeouts.push(window.setTimeout(f, t$$1));
63701     }
63702
63703
63704     function eventCancel() {
63705         event.stopPropagation();
63706         event.preventDefault();
63707     }
63708
63709
63710     function revealHouse(center, text$$1, options) {
63711         var padding = 160 * Math.pow(2, context.map().zoom() - 20);
63712         var box = pad$1(center, padding, context);
63713         reveal(box, text$$1, options);
63714     }
63715
63716
63717     function revealTank(center, text$$1, options) {
63718         var padding = 190 * Math.pow(2, context.map().zoom() - 19.5);
63719         var box = pad$1(center, padding, context);
63720         reveal(box, text$$1, options);
63721     }
63722
63723
63724     function revealEditMenu(loc, text$$1, options) {
63725         var rect = context.surfaceRect();
63726         var point = context.curtainProjection(loc);
63727         var pad = 40;
63728         var width = 250 + (2 * pad);
63729         var height = 350;
63730         var startX = rect.left + point[0];
63731         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
63732         var box = {
63733             left: left,
63734             top: point[1] + rect.top - 60,
63735             width: width,
63736             height: height
63737         };
63738         reveal(box, text$$1, options);
63739     }
63740
63741
63742     function addHouse() {
63743         context.enter(modeBrowse(context));
63744         context.history().reset('initial');
63745         houseId = null;
63746
63747         var msec = transitionTime(house, context.map().center());
63748         if (msec) { reveal(null, null, { duration: 0 }); }
63749         context.map().zoom(19).centerEase(house, msec);
63750
63751         timeout(function() {
63752             var tooltip = reveal('button.add-area',
63753                 t('intro.buildings.add_building', { button: icon('#icon-area', 'pre-text') }));
63754
63755             tooltip.selectAll('.tooltip-inner')
63756                 .insert('svg', 'span')
63757                 .attr('class', 'tooltip-illustration')
63758                 .append('use')
63759                 .attr('xlink:href', '#building-images');
63760
63761             context.on('enter.intro', function(mode) {
63762                 if (mode.id !== 'add-area') return;
63763                 continueTo(startHouse);
63764             });
63765         }, msec + 100);
63766
63767         function continueTo(nextStep) {
63768             context.on('enter.intro', null);
63769             nextStep();
63770         }
63771     }
63772
63773
63774     function startHouse() {
63775         if (context.mode().id !== 'add-area') {
63776             return continueTo(addHouse);
63777         }
63778
63779         houseId = null;
63780         context.map().zoomEase(20, 500);
63781
63782         timeout(function() {
63783             revealHouse(house, t('intro.buildings.start_building'));
63784
63785             context.map().on('move.intro drawn.intro', function() {
63786                 revealHouse(house, t('intro.buildings.start_building'), { duration: 0 });
63787             });
63788
63789             context.on('enter.intro', function(mode) {
63790                 if (mode.id !== 'draw-area') return chapter.restart();
63791                 continueTo(continueHouse);
63792             });
63793
63794         }, 550);  // after easing
63795
63796         function continueTo(nextStep) {
63797             context.map().on('move.intro drawn.intro', null);
63798             context.on('enter.intro', null);
63799             nextStep();
63800         }
63801     }
63802
63803
63804     function continueHouse() {
63805         if (context.mode().id !== 'draw-area') {
63806             return continueTo(addHouse);
63807         }
63808
63809         houseId = null;
63810
63811         revealHouse(house, t('intro.buildings.continue_building'));
63812
63813         context.map().on('move.intro drawn.intro', function() {
63814             revealHouse(house, t('intro.buildings.continue_building'), { duration: 0 });
63815         });
63816
63817         context.on('enter.intro', function(mode) {
63818             if (mode.id === 'draw-area') {
63819                 return;
63820             } else if (mode.id === 'select') {
63821                 var graph = context.graph(),
63822                     way = context.entity(context.selectedIDs()[0]),
63823                     nodes = graph.childNodes(way),
63824                     points = lodash.uniq(nodes).map(function(n) { return context.projection(n.loc); });
63825
63826                 if (isMostlySquare(points)) {
63827                     houseId = way.id;
63828                     return continueTo(chooseCategoryBuilding);
63829                 } else {
63830                     return continueTo(retryHouse);
63831                 }
63832
63833             } else {
63834                 return chapter.restart();
63835             }
63836         });
63837
63838         function continueTo(nextStep) {
63839             context.map().on('move.intro drawn.intro', null);
63840             context.on('enter.intro', null);
63841             nextStep();
63842         }
63843     }
63844
63845
63846     function retryHouse() {
63847         var onClick = function() { continueTo(addHouse); };
63848
63849         revealHouse(house, t('intro.buildings.retry_building'),
63850             { buttonText: t('intro.ok'), buttonCallback: onClick }
63851         );
63852
63853         context.map().on('move.intro drawn.intro', function() {
63854             revealHouse(house, t('intro.buildings.retry_building'),
63855                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
63856             );
63857         });
63858
63859         function continueTo(nextStep) {
63860             context.map().on('move.intro drawn.intro', null);
63861             nextStep();
63862         }
63863     }
63864
63865
63866     function chooseCategoryBuilding() {
63867         if (!houseId || !context.hasEntity(houseId)) {
63868             return addHouse();
63869         }
63870         var ids = context.selectedIDs();
63871         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
63872             context.enter(modeSelect(context, [houseId]));
63873         }
63874
63875         // disallow scrolling
63876         select('.inspector-wrap').on('wheel.intro', eventCancel);
63877
63878         timeout(function() {
63879             // reset pane, in case user somehow happened to change it..
63880             select('.inspector-wrap .panewrap').style('right', '-100%');
63881
63882             var button = select('.preset-category-building .preset-list-button');
63883
63884             reveal(button.node(),
63885                 t('intro.buildings.choose_category_building', { category: buildingCatetory.name() })
63886             );
63887
63888             button.on('click.intro', function() {
63889                 button.on('click.intro', null);
63890                 continueTo(choosePresetHouse);
63891             });
63892
63893         }, 400);  // after preset list pane visible..
63894
63895
63896         context.on('enter.intro', function(mode) {
63897             if (!houseId || !context.hasEntity(houseId)) {
63898                 return continueTo(addHouse);
63899             }
63900             var ids = context.selectedIDs();
63901             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
63902                 return continueTo(chooseCategoryBuilding);
63903             }
63904         });
63905
63906         function continueTo(nextStep) {
63907             select('.inspector-wrap').on('wheel.intro', null);
63908             select('.preset-list-button').on('click.intro', null);
63909             context.on('enter.intro', null);
63910             nextStep();
63911         }
63912     }
63913
63914
63915     function choosePresetHouse() {
63916         if (!houseId || !context.hasEntity(houseId)) {
63917             return addHouse();
63918         }
63919         var ids = context.selectedIDs();
63920         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
63921             context.enter(modeSelect(context, [houseId]));
63922         }
63923
63924         // disallow scrolling
63925         select('.inspector-wrap').on('wheel.intro', eventCancel);
63926
63927         timeout(function() {
63928             // reset pane, in case user somehow happened to change it..
63929             select('.inspector-wrap .panewrap').style('right', '-100%');
63930
63931             var button = select('.preset-building-house .preset-list-button');
63932
63933             reveal(button.node(),
63934                 t('intro.buildings.choose_preset_house', { preset: housePreset.name() }),
63935                 { duration: 300 }
63936             );
63937
63938             button.on('click.intro', function() {
63939                 button.on('click.intro', null);
63940                 continueTo(closeEditorHouse);
63941             });
63942
63943
63944         }, 400);  // after preset list pane visible..
63945
63946         context.on('enter.intro', function(mode) {
63947             if (!houseId || !context.hasEntity(houseId)) {
63948                 return continueTo(addHouse);
63949             }
63950             var ids = context.selectedIDs();
63951             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
63952                 return continueTo(chooseCategoryBuilding);
63953             }
63954         });
63955
63956         function continueTo(nextStep) {
63957             select('.inspector-wrap').on('wheel.intro', null);
63958             select('.preset-list-button').on('click.intro', null);
63959             context.on('enter.intro', null);
63960             nextStep();
63961         }
63962     }
63963
63964
63965     function closeEditorHouse() {
63966         if (!houseId || !context.hasEntity(houseId)) {
63967             return addHouse();
63968         }
63969         var ids = context.selectedIDs();
63970         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
63971             context.enter(modeSelect(context, [houseId]));
63972         }
63973
63974         context.history().checkpoint('hasHouse');
63975
63976         context.on('exit.intro', function() {
63977             continueTo(rightClickHouse);
63978         });
63979
63980         timeout(function() {
63981             reveal('.entity-editor-pane',
63982                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
63983             );
63984         }, 500);
63985
63986         function continueTo(nextStep) {
63987             context.on('exit.intro', null);
63988             nextStep();
63989         }
63990     }
63991
63992
63993     function rightClickHouse() {
63994         if (!houseId) return chapter.restart();
63995
63996         context.enter(modeBrowse(context));
63997         context.history().reset('hasHouse');
63998         context.map().centerEase(house, 500);
63999
64000         timeout(function() {
64001             if (context.map().zoom() < 20) {
64002                 context.map().zoomEase(20, 500);
64003             }
64004         }, 520);
64005
64006         context.on('enter.intro', function(mode) {
64007             if (mode.id !== 'select') return;
64008             var ids = context.selectedIDs();
64009             if (ids.length !== 1 || ids[0] !== houseId) return;
64010
64011             timeout(function() {
64012                 var node = selectMenuItem('orthogonalize').node();
64013                 if (!node) return;
64014                 continueTo(clickSquare);
64015             }, 300);  // after menu visible
64016         });
64017
64018         context.map().on('move.intro drawn.intro', function() {
64019             revealHouse(house, t('intro.buildings.rightclick_building'), { duration: 0 });
64020         });
64021
64022         context.history().on('change.intro', function() {
64023             continueTo(rightClickHouse);
64024         });
64025
64026         function continueTo(nextStep) {
64027             context.on('enter.intro', null);
64028             context.map().on('move.intro drawn.intro', null);
64029             context.history().on('change.intro', null);
64030             nextStep();
64031         }
64032     }
64033
64034
64035     function clickSquare() {
64036         if (!houseId) return chapter.restart();
64037         var entity = context.hasEntity(houseId);
64038         if (!entity) return continueTo(rightClickHouse);
64039
64040         var node = selectMenuItem('orthogonalize').node();
64041         if (!node) { return continueTo(rightClickHouse); }
64042
64043         var wasChanged = false;
64044         var menuCoords = context.map().mouseCoordinates();
64045
64046         revealEditMenu(menuCoords,
64047             t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') })
64048         );
64049
64050         context.on('enter.intro', function(mode) {
64051             if (mode.id === 'browse') {
64052                 continueTo(rightClickHouse);
64053             } else if (mode.id === 'move' || mode.id === 'rotate') {
64054                 continueTo(retryClickSquare);
64055             }
64056         });
64057
64058         context.map().on('move.intro drawn.intro', function() {
64059             var node = selectMenuItem('orthogonalize').node();
64060             if (!wasChanged && !node) { return continueTo(rightClickHouse); }
64061
64062             revealEditMenu(menuCoords,
64063                 t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') }),
64064                 { duration: 0 }
64065             );
64066         });
64067
64068         context.history().on('change.intro', function() {
64069             wasChanged = true;
64070             context.history().on('change.intro', null);
64071
64072             // Something changed.  Wait for transition to complete and check undo annotation.
64073             timeout(function() {
64074                 if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.area')) {
64075                     continueTo(doneSquare);
64076                 } else {
64077                     continueTo(retryClickSquare);
64078                 }
64079             }, 500);  // after transitioned actions
64080         });
64081
64082         function continueTo(nextStep) {
64083             context.on('enter.intro', null);
64084             context.map().on('move.intro drawn.intro', null);
64085             context.history().on('change.intro', null);
64086             nextStep();
64087         }
64088     }
64089
64090
64091     function retryClickSquare() {
64092         context.enter(modeBrowse(context));
64093
64094         revealHouse(house, t('intro.buildings.retry_square'), {
64095             buttonText: t('intro.ok'),
64096             buttonCallback: function() { continueTo(rightClickHouse); }
64097         });
64098
64099         function continueTo(nextStep) {
64100             nextStep();
64101         }
64102     }
64103
64104
64105     function doneSquare() {
64106         context.history().checkpoint('doneSquare');
64107
64108         revealHouse(house, t('intro.buildings.done_square'), {
64109             buttonText: t('intro.ok'),
64110             buttonCallback: function() { continueTo(addTank); }
64111         });
64112
64113         function continueTo(nextStep) {
64114             nextStep();
64115         }
64116     }
64117
64118
64119     function addTank() {
64120         context.enter(modeBrowse(context));
64121         context.history().reset('doneSquare');
64122         tankId = null;
64123
64124         var msec = transitionTime(tank, context.map().center());
64125         if (msec) { reveal(null, null, { duration: 0 }); }
64126         context.map().zoom(19.5).centerEase(tank, msec);
64127
64128         timeout(function() {
64129             reveal('button.add-area',
64130                 t('intro.buildings.add_tank', { button: icon('#icon-area', 'pre-text') })
64131             );
64132
64133             context.on('enter.intro', function(mode) {
64134                 if (mode.id !== 'add-area') return;
64135                 continueTo(startTank);
64136             });
64137         }, msec + 100);
64138
64139         function continueTo(nextStep) {
64140             context.on('enter.intro', null);
64141             nextStep();
64142         }
64143     }
64144
64145
64146     function startTank() {
64147         if (context.mode().id !== 'add-area') {
64148             return continueTo(addTank);
64149         }
64150
64151         tankId = null;
64152
64153         timeout(function() {
64154             revealTank(tank, t('intro.buildings.start_tank'));
64155
64156             context.map().on('move.intro drawn.intro', function() {
64157                 revealTank(tank, t('intro.buildings.start_tank'), { duration: 0 });
64158             });
64159
64160             context.on('enter.intro', function(mode) {
64161                 if (mode.id !== 'draw-area') return chapter.restart();
64162                 continueTo(continueTank);
64163             });
64164
64165         }, 550);  // after easing
64166
64167         function continueTo(nextStep) {
64168             context.map().on('move.intro drawn.intro', null);
64169             context.on('enter.intro', null);
64170             nextStep();
64171         }
64172     }
64173
64174
64175     function continueTank() {
64176         if (context.mode().id !== 'draw-area') {
64177             return continueTo(addTank);
64178         }
64179
64180         tankId = null;
64181
64182         revealTank(tank, t('intro.buildings.continue_tank'));
64183
64184         context.map().on('move.intro drawn.intro', function() {
64185             revealTank(tank, t('intro.buildings.continue_tank'), { duration: 0 });
64186         });
64187
64188         context.on('enter.intro', function(mode) {
64189             if (mode.id === 'draw-area') {
64190                 return;
64191             } else if (mode.id === 'select') {
64192                 tankId = context.selectedIDs()[0];
64193                 return continueTo(searchPresetTank);
64194             } else {
64195                 return continueTo(addTank);
64196             }
64197         });
64198
64199         function continueTo(nextStep) {
64200             context.map().on('move.intro drawn.intro', null);
64201             context.on('enter.intro', null);
64202             nextStep();
64203         }
64204     }
64205
64206
64207     function searchPresetTank() {
64208         if (!tankId || !context.hasEntity(tankId)) {
64209             return addTank();
64210         }
64211         var ids = context.selectedIDs();
64212         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
64213             context.enter(modeSelect(context, [tankId]));
64214         }
64215
64216         // disallow scrolling
64217         select('.inspector-wrap').on('wheel.intro', eventCancel);
64218
64219         timeout(function() {
64220             // reset pane, in case user somehow happened to change it..
64221             select('.inspector-wrap .panewrap').style('right', '-100%');
64222
64223             select('.preset-search-input')
64224                 .on('keydown.intro', null)
64225                 .on('keyup.intro', checkPresetSearch);
64226
64227             reveal('.preset-search-input',
64228                 t('intro.buildings.search_tank', { preset: tankPreset.name() })
64229             );
64230         }, 400);  // after preset list pane visible..
64231
64232         context.on('enter.intro', function(mode) {
64233             if (!tankId || !context.hasEntity(tankId)) {
64234                 return continueTo(addTank);
64235             }
64236
64237             var ids = context.selectedIDs();
64238             if (mode.id !== 'select' || !ids.length || ids[0] !== tankId) {
64239                 // keep the user's area selected..
64240                 context.enter(modeSelect(context, [tankId]));
64241
64242                 // reset pane, in case user somehow happened to change it..
64243                 select('.inspector-wrap .panewrap').style('right', '-100%');
64244                 // disallow scrolling
64245                 select('.inspector-wrap').on('wheel.intro', eventCancel);
64246
64247                 select('.preset-search-input')
64248                     .on('keydown.intro', null)
64249                     .on('keyup.intro', checkPresetSearch);
64250
64251                 reveal('.preset-search-input',
64252                     t('intro.buildings.search_tank', { preset: tankPreset.name() })
64253                 );
64254
64255                 context.history().on('change.intro', null);
64256             }
64257         });
64258
64259         function checkPresetSearch() {
64260             var first = select('.preset-list-item:first-child');
64261
64262             if (first.classed('preset-man_made-storage_tank')) {
64263                 reveal(first.select('.preset-list-button').node(),
64264                     t('intro.buildings.choose_tank', { preset: tankPreset.name() }),
64265                     { duration: 300 }
64266                 );
64267
64268                 select('.preset-search-input')
64269                     .on('keydown.intro', eventCancel, true)
64270                     .on('keyup.intro', null);
64271
64272                 context.history().on('change.intro', function() {
64273                     continueTo(closeEditorTank);
64274                 });
64275             }
64276         }
64277
64278         function continueTo(nextStep) {
64279             select('.inspector-wrap').on('wheel.intro', null);
64280             context.on('enter.intro', null);
64281             context.history().on('change.intro', null);
64282             select('.preset-search-input').on('keydown.intro keyup.intro', null);
64283             nextStep();
64284         }
64285     }
64286
64287
64288     function closeEditorTank() {
64289         if (!tankId || !context.hasEntity(tankId)) {
64290             return addTank();
64291         }
64292         var ids = context.selectedIDs();
64293         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
64294             context.enter(modeSelect(context, [tankId]));
64295         }
64296
64297         context.history().checkpoint('hasTank');
64298
64299         context.on('exit.intro', function() {
64300             continueTo(rightClickTank);
64301         });
64302
64303         timeout(function() {
64304             reveal('.entity-editor-pane',
64305                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
64306             );
64307         }, 500);
64308
64309         function continueTo(nextStep) {
64310             context.on('exit.intro', null);
64311             nextStep();
64312         }
64313     }
64314
64315
64316     function rightClickTank() {
64317         if (!tankId) return continueTo(addTank);
64318
64319         context.enter(modeBrowse(context));
64320         context.history().reset('hasTank');
64321         context.map().centerEase(tank, 500);
64322
64323         timeout(function() {
64324             context.on('enter.intro', function(mode) {
64325                 if (mode.id !== 'select') return;
64326                 var ids = context.selectedIDs();
64327                 if (ids.length !== 1 || ids[0] !== tankId) return;
64328
64329                 timeout(function() {
64330                     var node = selectMenuItem('circularize').node();
64331                     if (!node) return;
64332                     continueTo(clickCircle);
64333                 }, 300);  // after menu visible
64334             });
64335
64336             revealTank(tank, t('intro.buildings.rightclick_tank'));
64337
64338             context.map().on('move.intro drawn.intro', function() {
64339                 revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 });
64340             });
64341
64342             context.history().on('change.intro', function() {
64343                 continueTo(rightClickTank);
64344             });
64345
64346         }, 600);
64347
64348         function continueTo(nextStep) {
64349             context.on('enter.intro', null);
64350             context.map().on('move.intro drawn.intro', null);
64351             context.history().on('change.intro', null);
64352             nextStep();
64353         }
64354     }
64355
64356
64357     function clickCircle() {
64358         if (!tankId) return chapter.restart();
64359         var entity = context.hasEntity(tankId);
64360         if (!entity) return continueTo(rightClickTank);
64361
64362         var node = selectMenuItem('circularize').node();
64363         if (!node) { return continueTo(rightClickTank); }
64364
64365         var wasChanged = false;
64366         var menuCoords = context.map().mouseCoordinates();
64367
64368         revealEditMenu(menuCoords,
64369             t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') })
64370         );
64371
64372         context.on('enter.intro', function(mode) {
64373             if (mode.id === 'browse') {
64374                 continueTo(rightClickTank);
64375             } else if (mode.id === 'move' || mode.id === 'rotate') {
64376                 continueTo(retryClickCircle);
64377             }
64378         });
64379
64380         context.map().on('move.intro drawn.intro', function() {
64381             var node = selectMenuItem('circularize').node();
64382             if (!wasChanged && !node) { return continueTo(rightClickTank); }
64383
64384             revealEditMenu(menuCoords,
64385                 t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') }),
64386                 { duration: 0 }
64387             );
64388         });
64389
64390         context.history().on('change.intro', function() {
64391             wasChanged = true;
64392             context.history().on('change.intro', null);
64393
64394             // Something changed.  Wait for transition to complete and check undo annotation.
64395             timeout(function() {
64396                 if (context.history().undoAnnotation() === t('operations.circularize.annotation.area')) {
64397                     continueTo(play);
64398                 } else {
64399                     continueTo(retryClickCircle);
64400                 }
64401             }, 500);  // after transitioned actions
64402         });
64403
64404         function continueTo(nextStep) {
64405             context.on('enter.intro', null);
64406             context.map().on('move.intro drawn.intro', null);
64407             context.history().on('change.intro', null);
64408             nextStep();
64409         }
64410     }
64411
64412
64413     function retryClickCircle() {
64414         context.enter(modeBrowse(context));
64415
64416         revealTank(tank, t('intro.buildings.retry_circle'), {
64417             buttonText: t('intro.ok'),
64418             buttonCallback: function() { continueTo(rightClickTank); }
64419         });
64420
64421         function continueTo(nextStep) {
64422             nextStep();
64423         }
64424     }
64425
64426
64427     function play() {
64428         dispatch$$1.call('done');
64429         reveal('#id-container',
64430             t('intro.buildings.play', { next: t('intro.startediting.title') }), {
64431                 tooltipBox: '.intro-nav-wrap .chapter-startEditing',
64432                 buttonText: t('intro.ok'),
64433                 buttonCallback: function() { reveal('#id-container'); }
64434             }
64435         );
64436     }
64437
64438
64439     chapter.enter = function() {
64440         addHouse();
64441     };
64442
64443
64444     chapter.exit = function() {
64445         timeouts.forEach(window.clearTimeout);
64446         context.on('enter.intro exit.intro', null);
64447         context.map().on('move.intro drawn.intro', null);
64448         context.history().on('change.intro', null);
64449         select('.inspector-wrap').on('wheel.intro', null);
64450         select('.preset-search-input').on('keydown.intro keyup.intro', null);
64451         select('.more-fields .combobox-input').on('click.intro', null);
64452     };
64453
64454
64455     chapter.restart = function() {
64456         chapter.exit();
64457         chapter.enter();
64458     };
64459
64460
64461     return utilRebind(chapter, dispatch$$1, 'on');
64462 }
64463
64464 function uiIntroStartEditing(context, reveal) {
64465     var dispatch$$1 = dispatch('done', 'startEditing'),
64466         modalSelection = select(null);
64467
64468
64469     var chapter = {
64470         title: 'intro.startediting.title'
64471     };
64472
64473     function showHelp() {
64474         reveal('.map-control.help-control',
64475             t('intro.startediting.help', { button: icon('#icon-help', 'pre-text'), key: t('help.key') }), {
64476                 buttonText: t('intro.ok'),
64477                 buttonCallback: function() { shortcuts(); }
64478             }
64479         );
64480     }
64481
64482     function shortcuts() {
64483         reveal('.map-control.help-control',
64484             t('intro.startediting.shortcuts', { key: t('shortcuts.toggle.key') }), {
64485                 buttonText: t('intro.ok'),
64486                 buttonCallback: function() { showSave(); }
64487             }
64488         );
64489     }
64490
64491     function showSave() {
64492         selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
64493         reveal('#bar button.save',
64494             t('intro.startediting.save'), {
64495                 buttonText: t('intro.ok'),
64496                 buttonCallback: function() { showStart(); }
64497             }
64498         );
64499     }
64500
64501     function showStart() {
64502         selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
64503
64504         modalSelection = uiModal(context.container());
64505
64506         modalSelection.select('.modal')
64507             .attr('class', 'modal-splash modal col6');
64508
64509         modalSelection.selectAll('.close').remove();
64510
64511         var startbutton = modalSelection.select('.content')
64512             .attr('class', 'fillL')
64513             .append('button')
64514                 .attr('class', 'modal-section huge-modal-button')
64515                 .on('click', function() {
64516                     modalSelection.remove();
64517                 });
64518
64519             startbutton
64520                 .append('svg')
64521                 .attr('class', 'illustration')
64522                 .append('use')
64523                 .attr('xlink:href', '#logo-walkthrough');
64524
64525             startbutton
64526                 .append('h2')
64527                 .text(t('intro.startediting.start'));
64528
64529         dispatch$$1.call('startEditing');
64530     }
64531
64532
64533     chapter.enter = function() {
64534         showHelp();
64535     };
64536
64537
64538     chapter.exit = function() {
64539         modalSelection.remove();
64540         selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
64541     };
64542
64543
64544     return utilRebind(chapter, dispatch$$1, 'on');
64545 }
64546
64547 var chapterUi = {
64548     welcome: uiIntroWelcome,
64549     navigation: uiIntroNavigation,
64550     point: uiIntroPoint,
64551     area: uiIntroArea,
64552     line: uiIntroLine,
64553     building: uiIntroBuilding,
64554     startEditing: uiIntroStartEditing
64555 };
64556
64557 var chapterFlow = [
64558     'welcome',
64559     'navigation',
64560     'point',
64561     'area',
64562     'line',
64563     'building',
64564     'startEditing'
64565 ];
64566
64567
64568 function uiIntro(context) {
64569     var introGraph = {},
64570         currChapter;
64571
64572
64573     // create entities for intro graph and localize names
64574     for (var id in dataIntroGraph) {
64575         introGraph[id] = osmEntity$$1(localize(dataIntroGraph[id]));
64576     }
64577
64578
64579     function intro(selection$$1) {
64580         context.enter(modeBrowse(context));
64581
64582         // Save current map state
64583         var osm = context.connection(),
64584             history = context.history().toJSON(),
64585             hash = window.location.hash,
64586             center = context.map().center(),
64587             zoom$$1 = context.map().zoom(),
64588             background = context.background().baseLayerSource(),
64589             overlays = context.background().overlayLayerSources(),
64590             opacity = selectAll('#map .layer-background').style('opacity'),
64591             loadedTiles = osm && osm.loadedTiles(),
64592             baseEntities = context.history().graph().base().entities,
64593             countryCode = services.geocoder.countryCode;
64594
64595         // Block saving
64596         context.inIntro(true);
64597
64598         // Load semi-real data used in intro
64599         if (osm) { osm.toggle(false).reset(); }
64600         context.history().reset();
64601         context.history().merge(values(coreGraph$$1().load(introGraph).entities));
64602         context.history().checkpoint('initial');
64603         context.background().bing();
64604         overlays.forEach(function (d) { context.background().toggleOverlayLayer(d); });
64605
64606         // Mock geocoder
64607         services.geocoder.countryCode = function(location, callback) {
64608             callback(null, t('intro.graph.countrycode'));
64609         };
64610
64611         selectAll('#map .layer-background').style('opacity', 1);
64612
64613         var curtain = uiCurtain();
64614         selection$$1.call(curtain);
64615
64616         // store that the user started the walkthrough..
64617         context.storage('walkthrough_started', 'yes');
64618
64619         // restore previous walkthrough progress..
64620         var storedProgress = context.storage('walkthrough_progress') || '';
64621         var progress = storedProgress.split(';').filter(Boolean);
64622
64623         var chapters = chapterFlow.map(function(chapter, i) {
64624             var s = chapterUi[chapter](context, curtain.reveal)
64625                 .on('done', function() {
64626                     context.presets().init();  // clear away "recent" presets
64627
64628                     buttons.filter(function(d) {
64629                         return d.title === s.title;
64630                     }).classed('finished', true);
64631
64632                     if (i < chapterFlow.length - 1) {
64633                         var next = chapterFlow[i + 1];
64634                         select('button.chapter-' + next)
64635                             .classed('next', true);
64636                     }
64637
64638                     // store walkthrough progress..
64639                     progress.push(chapter);
64640                     context.storage('walkthrough_progress', lodash.uniq(progress).join(';'));
64641                 });
64642             return s;
64643         });
64644
64645         chapters[chapters.length - 1].on('startEditing', function() {
64646             // store walkthrough progress..
64647             progress.push('startEditing');
64648             context.storage('walkthrough_progress', lodash.uniq(progress).join(';'));
64649
64650             // store if walkthrough is completed..
64651             var incomplete = lodash.difference(chapterFlow, progress);
64652             if (!incomplete.length) {
64653                 context.storage('walkthrough_completed', 'yes');
64654             }
64655
64656             curtain.remove();
64657             navwrap.remove();
64658             selectAll('#map .layer-background').style('opacity', opacity);
64659             if (osm) { osm.toggle(true).reset().loadedTiles(loadedTiles); }
64660             context.history().reset().merge(values(baseEntities));
64661             context.background().baseLayerSource(background);
64662             overlays.forEach(function (d) { context.background().toggleOverlayLayer(d); });
64663             if (history) { context.history().fromJSON(history, false); }
64664             context.map().centerZoom(center, zoom$$1);
64665             window.location.replace(hash);
64666             services.geocoder.countryCode = countryCode;
64667             context.inIntro(false);
64668         });
64669
64670         var navwrap = selection$$1
64671             .append('div')
64672             .attr('class', 'intro-nav-wrap fillD');
64673
64674         navwrap
64675             .append('svg')
64676             .attr('class', 'intro-nav-wrap-logo')
64677             .append('use')
64678             .attr('xlink:href', '#logo-walkthrough');
64679
64680         var buttonwrap = navwrap
64681             .append('div')
64682             .attr('class', 'joined')
64683             .selectAll('button.chapter');
64684
64685         var buttons = buttonwrap
64686             .data(chapters)
64687             .enter()
64688             .append('button')
64689             .attr('class', function(d, i) { return 'chapter chapter-' + chapterFlow[i]; })
64690             .on('click', enterChapter);
64691
64692         buttons
64693             .append('span')
64694             .text(function(d) { return t(d.title); });
64695
64696         buttons
64697             .append('span')
64698             .attr('class', 'status')
64699             .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'));
64700
64701         enterChapter(chapters[0]);
64702
64703
64704         function enterChapter(newChapter) {
64705             if (currChapter) { currChapter.exit(); }
64706             context.enter(modeBrowse(context));
64707
64708             currChapter = newChapter;
64709             currChapter.enter();
64710
64711             buttons
64712                 .classed('next', false)
64713                 .classed('active', function(d) {
64714                     return d.title === currChapter.title;
64715                 });
64716         }
64717     }
64718
64719
64720     return intro;
64721 }
64722
64723 function uiShortcuts() {
64724     var detected = utilDetect();
64725     var activeTab = 0;
64726     var modalSelection;
64727     var savedSelection;
64728
64729
64730     var keybinding = d3keybinding('shortcuts')
64731         .on(t('shortcuts.toggle.key'), function () {
64732             if (selectAll('.modal-shortcuts').size()) {  // already showing
64733                 if (modalSelection) {
64734                     modalSelection.close();
64735                     modalSelection = null;
64736                 }
64737             } else {
64738                 modalSelection = uiModal(savedSelection);
64739                 shortcutsModal(modalSelection);
64740             }
64741         });
64742
64743     select(document)
64744         .call(keybinding);
64745
64746
64747
64748     function shortcutsModal(modalSelection) {
64749         modalSelection.select('.modal')
64750             .classed('modal-shortcuts', true);
64751
64752         var shortcutsModal = modalSelection.select('.content');
64753
64754         shortcutsModal
64755             .append('div')
64756             .attr('class', 'modal-section')
64757             .append('h3')
64758             .text(t('shortcuts.title'));
64759
64760         shortcutsModal
64761             .call(render);
64762     }
64763
64764
64765     function render(selection$$1) {
64766         var wrapper = selection$$1
64767             .selectAll('.wrapper')
64768             .data([0]);
64769
64770         var wrapperEnter = wrapper
64771             .enter()
64772             .append('div')
64773             .attr('class', 'wrapper modal-section');
64774
64775         var tabsBar = wrapperEnter
64776             .append('div')
64777             .attr('class', 'tabs-bar');
64778
64779         var shortcutsList = wrapperEnter
64780             .append('div')
64781             .attr('class', 'shortcuts-list');
64782
64783         wrapper = wrapper.merge(wrapperEnter);
64784
64785         var tabs = tabsBar
64786             .selectAll('.tab')
64787             .data(dataShortcuts);
64788
64789         var tabsEnter = tabs
64790             .enter()
64791             .append('div')
64792             .attr('class', 'tab')
64793             .on('click', function (d, i) {
64794                 activeTab = i;
64795                 render(selection$$1);
64796             });
64797
64798         tabsEnter
64799             .append('span')
64800             .text(function (d) { return t(d.text); });
64801
64802         tabs = tabs
64803             .merge(tabsEnter);
64804
64805         // Update
64806         wrapper.selectAll('.tab')
64807             .classed('active', function (d, i) {
64808                 return i === activeTab;
64809             });
64810
64811
64812         var shortcuts = shortcutsList
64813             .selectAll('.shortcut-tab')
64814             .data(dataShortcuts);
64815
64816         var shortcutsEnter = shortcuts
64817             .enter()
64818             .append('div')
64819             .attr('class', function(d) { return 'shortcut-tab shortcut-tab-' + d.tab; });
64820
64821         var columnsEnter = shortcutsEnter
64822             .selectAll('.shortcut-column')
64823             .data(function (d) { return d.columns; })
64824             .enter()
64825             .append('table')
64826             .attr('class', 'shortcut-column');
64827
64828         var rowsEnter = columnsEnter
64829             .selectAll('.shortcut-row')
64830             .data(function (d) { return d.rows; })
64831             .enter()
64832             .append('tr')
64833             .attr('class', 'shortcut-row');
64834
64835
64836         var sectionRows = rowsEnter
64837             .filter(function (d) { return !d.shortcuts; });
64838
64839         sectionRows
64840             .append('td');
64841
64842         sectionRows
64843             .append('td')
64844             .attr('class', 'shortcut-section')
64845             .append('h3')
64846             .text(function (d) { return t(d.text); });
64847
64848
64849         var shortcutRows = rowsEnter
64850             .filter(function (d) { return d.shortcuts; });
64851
64852         var shortcutKeys = shortcutRows
64853             .append('td')
64854             .attr('class', 'shortcut-keys');
64855
64856         var modifierKeys = shortcutKeys
64857             .filter(function (d) { return d.modifiers; });
64858
64859         modifierKeys
64860             .selectAll('kbd.modifier')
64861             .data(function (d) {
64862                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
64863                     return ['⌘'];
64864                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
64865                     return [];
64866                 } else {
64867                     return d.modifiers;
64868                 }
64869             })
64870             .enter()
64871             .each(function () {
64872                 var selection$$1 = select(this);
64873
64874                 selection$$1
64875                     .append('kbd')
64876                     .attr('class', 'modifier')
64877                     .text(function (d) { return uiCmd.display(d); });
64878
64879                 selection$$1
64880                     .append('span')
64881                     .text('+');
64882             });
64883
64884
64885         shortcutKeys
64886             .selectAll('kbd.shortcut')
64887             .data(function (d) {
64888                 var arr = d.shortcuts;
64889                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
64890                     arr = ['Y'];
64891                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
64892                     arr = ['F11'];
64893                 }
64894
64895                 return arr.map(function(s) {
64896                     return {
64897                         shortcut: s,
64898                         separator: d.separator
64899                     };
64900                 });
64901             })
64902             .enter()
64903             .each(function (d, i, nodes) {
64904                 var selection$$1 = select(this);
64905                 var click = d.shortcut.toLowerCase().match(/(.*).click/);
64906
64907                 if (click && click[1]) {
64908                     selection$$1
64909                         .call(svgIcon('#walkthrough-mouse', 'mouseclick', click[1]));
64910                 } else {
64911                     selection$$1
64912                         .append('kbd')
64913                         .attr('class', 'shortcut')
64914                         .text(function (d) {
64915                             var key = d.shortcut;
64916                             return key.indexOf('.') !== -1 ? uiCmd.display(t(key)) : uiCmd.display(key);
64917                         });
64918                 }
64919
64920                 if (i < nodes.length - 1) {
64921                     selection$$1
64922                         .append('span')
64923                         .text(d.separator || '\u00a0' + t('shortcuts.or') + '\u00a0');
64924                 }
64925             });
64926
64927
64928         shortcutKeys
64929             .filter(function(d) { return d.gesture; })
64930             .each(function () {
64931                 var selection$$1 = select(this);
64932
64933                 selection$$1
64934                     .append('span')
64935                     .text('+');
64936
64937                 selection$$1
64938                     .append('span')
64939                     .attr('class', 'gesture')
64940                     .text(function (d) { return t(d.gesture); });
64941             });
64942
64943
64944         shortcutRows
64945             .append('td')
64946             .attr('class', 'shortcut-desc')
64947             .text(function (d) { return d.text ? t(d.text) : '\u00a0'; });
64948
64949
64950         shortcuts = shortcuts
64951             .merge(shortcutsEnter);
64952
64953         // Update
64954         wrapper.selectAll('.shortcut-tab')
64955             .style('display', function (d, i) {
64956                 return i === activeTab ? 'flex' : 'none';
64957             });
64958     }
64959
64960
64961     return function(selection$$1, show) {
64962         savedSelection = selection$$1;
64963         if (show) {
64964             modalSelection = uiModal(selection$$1);
64965             shortcutsModal(modalSelection);
64966         }
64967     };
64968 }
64969
64970 function uiHelp(context) {
64971     var key = t('help.key');
64972
64973     var docKeys = [
64974         'help.help',
64975         'help.editing_saving',
64976         'help.roads',
64977         'help.gps',
64978         'help.imagery',
64979         'help.addresses',
64980         'help.inspector',
64981         'help.buildings',
64982         'help.relations'];
64983
64984     var docs = docKeys.map(function(key) {
64985         var text$$1 = t(key);
64986         return {
64987             title: text$$1.split('\n')[0].replace('#', '').trim(),
64988             html: marked(text$$1.split('\n').slice(1).join('\n'))
64989         };
64990     });
64991
64992
64993     function help(selection$$1) {
64994
64995         function hide() {
64996             setVisible(false);
64997         }
64998
64999
65000         function toggle() {
65001             if (event) event.preventDefault();
65002             tooltipBehavior.hide(button);
65003             setVisible(!button.classed('active'));
65004         }
65005
65006
65007         function setVisible(show) {
65008             if (show !== shown) {
65009                 button.classed('active', show);
65010                 shown = show;
65011
65012                 if (show) {
65013                     selection$$1.on('mousedown.help-inside', function() {
65014                         return event.stopPropagation();
65015                     });
65016                     pane.style('display', 'block')
65017                         .style('right', '-500px')
65018                         .transition()
65019                         .duration(200)
65020                         .style('right', '0px');
65021                 } else {
65022                     pane.style('right', '0px')
65023                         .transition()
65024                         .duration(200)
65025                         .style('right', '-500px')
65026                         .on('end', function() {
65027                             select(this).style('display', 'none');
65028                         });
65029                     selection$$1.on('mousedown.help-inside', null);
65030                 }
65031             }
65032         }
65033
65034
65035         function clickHelp(d, i) {
65036             var rtl = (textDirection === 'rtl');
65037             pane.property('scrollTop', 0);
65038             doctitle.html(d.title);
65039
65040             body.html(d.html);
65041             body.selectAll('a')
65042                 .attr('target', '_blank');
65043             menuItems.classed('selected', function(m) {
65044                 return m.title === d.title;
65045             });
65046
65047             nav.html('');
65048             if (rtl) {
65049                 nav.call(drawNext).call(drawPrevious);
65050             } else {
65051                 nav.call(drawPrevious).call(drawNext);
65052             }
65053
65054
65055             function drawNext(selection$$1) {
65056                 if (i < docs.length - 1) {
65057                     var nextLink = selection$$1
65058                         .append('a')
65059                         .attr('class', 'next')
65060                         .on('click', function() {
65061                             clickHelp(docs[i + 1], i + 1);
65062                         });
65063
65064                     nextLink
65065                         .append('span')
65066                         .text(docs[i + 1].title)
65067                         .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline'));
65068                 }
65069             }
65070
65071
65072             function drawPrevious(selection$$1) {
65073                 if (i > 0) {
65074                     var prevLink = selection$$1
65075                         .append('a')
65076                         .attr('class', 'previous')
65077                         .on('click', function() {
65078                             clickHelp(docs[i - 1], i - 1);
65079                         });
65080
65081                     prevLink
65082                         .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline'))
65083                         .append('span')
65084                         .text(docs[i - 1].title);
65085                 }
65086             }
65087         }
65088
65089
65090         function clickWalkthrough() {
65091             if (context.inIntro()) return;
65092             context.container().call(uiIntro(context));
65093             setVisible(false);
65094         }
65095
65096
65097         function clickShortcuts() {
65098             context.container().call(uiShortcuts(context), true);
65099         }
65100
65101
65102         var pane = selection$$1.append('div')
65103                 .attr('class', 'help-wrap map-overlay fillL col5 content hide'),
65104             tooltipBehavior = tooltip()
65105                 .placement((textDirection === 'rtl') ? 'right' : 'left')
65106                 .html(true)
65107                 .title(uiTooltipHtml(t('help.title'), key)),
65108             button = selection$$1.append('button')
65109                 .attr('tabindex', -1)
65110                 .on('click', toggle)
65111                 .call(svgIcon('#icon-help', 'light'))
65112                 .call(tooltipBehavior),
65113             shown = false;
65114
65115
65116         var toc = pane.append('ul')
65117             .attr('class', 'toc');
65118
65119         var menuItems = toc.selectAll('li')
65120             .data(docs)
65121             .enter()
65122             .append('li')
65123             .append('a')
65124             .html(function(d) { return d.title; })
65125             .on('click', clickHelp);
65126
65127         var shortcuts = toc
65128             .append('li')
65129             .attr('class', 'shortcuts')
65130             .call(tooltip()
65131                 .html(true)
65132                 .title(uiTooltipHtml(t('shortcuts.tooltip'), '?'))
65133                 .placement('top')
65134             )
65135             .append('a')
65136             .on('click', clickShortcuts);
65137
65138         shortcuts
65139             .append('div')
65140             .text(t('shortcuts.title'));
65141
65142         var walkthrough = toc
65143             .append('li')
65144             .attr('class', 'walkthrough')
65145             .append('a')
65146             .on('click', clickWalkthrough);
65147
65148         walkthrough
65149             .append('svg')
65150             .attr('class', 'logo logo-walkthrough')
65151             .append('use')
65152             .attr('xlink:href', '#logo-walkthrough');
65153
65154         walkthrough
65155             .append('div')
65156             .text(t('splash.walkthrough'));
65157
65158
65159         var content = pane.append('div')
65160             .attr('class', 'left-content');
65161
65162         var doctitle = content.append('h2')
65163             .text(t('help.title'));
65164
65165         var body = content.append('div')
65166             .attr('class', 'body');
65167
65168         var nav = content.append('div')
65169             .attr('class', 'nav');
65170
65171         clickHelp(docs[0], 0);
65172
65173         var keybinding = d3keybinding('help')
65174             .on(key, toggle)
65175             .on([t('background.key'), t('map_data.key')], hide);
65176
65177         select(document)
65178             .call(keybinding);
65179
65180         context.surface().on('mousedown.help-outside', hide);
65181         context.container().on('mousedown.help-outside', hide);
65182     }
65183
65184     return help;
65185 }
65186
65187 function uiPanelBackground(context) {
65188     var background = context.background();
65189     var currSource = null;
65190     var currZoom = '';
65191     var currVintage = '';
65192
65193
65194     function redraw(selection$$1) {
65195         if (currSource !== background.baseLayerSource().name()) {
65196             currSource = background.baseLayerSource().name();
65197             currZoom = '';
65198             currVintage = '';
65199         }
65200
65201         selection$$1.html('');
65202
65203         var list = selection$$1
65204             .append('ul')
65205             .attr('class', 'background-info');
65206
65207         list
65208             .append('li')
65209             .text(currSource);
65210
65211         list
65212             .append('li')
65213             .text(t('info_panels.background.zoom') + ': ')
65214             .append('span')
65215             .attr('class', 'zoom')
65216             .text(currZoom);
65217
65218         list
65219             .append('li')
65220             .text(t('info_panels.background.vintage') + ': ')
65221             .append('span')
65222             .attr('class', 'vintage')
65223             .text(currVintage);
65224
65225         if (!currVintage) {
65226             debouncedGetVintage(selection$$1);
65227         }
65228
65229         var toggle = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles';
65230
65231         selection$$1
65232             .append('a')
65233             .text(t('info_panels.background.' + toggle))
65234             .attr('href', '#')
65235             .attr('class', 'button button-toggle-tiles')
65236             .on('click', function() {
65237                 event.preventDefault();
65238                 context.setDebug('tile', !context.getDebug('tile'));
65239                 selection$$1.call(redraw);
65240             });
65241     }
65242
65243
65244     var debouncedGetVintage = lodash.debounce(getVintage, 250);
65245     function getVintage(selection$$1) {
65246         var tile = select('.layer-background img.tile-center');   // tile near viewport center
65247         if (tile.empty()) return;
65248
65249         var d = tile.datum(),
65250             zoom$$1 = (d && d.length >= 3 && d[2]) || Math.floor(context.map().zoom()),
65251             center = context.map().center();
65252
65253         currZoom = String(zoom$$1);
65254         selection$$1.selectAll('.zoom')
65255             .text(currZoom);
65256
65257         if (!d || !d.length >= 3) return;
65258         background.baseLayerSource().getVintage(center, d, function(err, result) {
65259             currVintage = (result && result.range) || t('info_panels.background.unknown');
65260             selection$$1.selectAll('.vintage')
65261                 .text(currVintage);
65262         });
65263     }
65264
65265
65266     var panel = function(selection$$1) {
65267         selection$$1.call(redraw);
65268
65269         context.map()
65270             .on('drawn.info-background', function() {
65271                 selection$$1.call(redraw);
65272             })
65273             .on('move.info-background', function() {
65274                 selection$$1.call(debouncedGetVintage);
65275             });
65276
65277     };
65278
65279     panel.off = function() {
65280         context.map()
65281             .on('drawn.info-background', null)
65282             .on('move.info-background', null);
65283     };
65284
65285     panel.id = 'background';
65286     panel.title = t('info_panels.background.title');
65287     panel.key = t('info_panels.background.key');
65288
65289
65290     return panel;
65291 }
65292
65293 function uiPanelHistory(context) {
65294     var osm;
65295
65296     function displayTimestamp(entity) {
65297         if (!entity.timestamp) return t('info_panels.history.unknown');
65298
65299         var d = new Date(entity.timestamp);
65300         if (isNaN(d.getTime())) return t('info_panels.history.unknown');
65301
65302         return d.toLocaleString();
65303     }
65304
65305
65306     function displayUser(selection, entity) {
65307         if (!entity.user) {
65308             selection
65309                 .append('span')
65310                 .text(t('info_panels.history.unknown'));
65311             return;
65312         }
65313
65314         selection
65315             .append('span')
65316             .attr('class', 'user-name')
65317             .text(entity.user);
65318
65319         var links = selection
65320             .append('div')
65321             .attr('class', 'links');
65322
65323         if (osm) {
65324             links
65325                 .append('a')
65326                 .attr('class', 'user-osm-link')
65327                 .attr('href', osm.userURL(entity.user))
65328                 .attr('target', '_blank')
65329                 .attr('tabindex', -1)
65330                 .text('OSM');
65331         }
65332
65333         links
65334             .append('a')
65335             .attr('class', 'user-hdyc-link')
65336             .attr('href', 'https://hdyc.neis-one.org/?' + entity.user)
65337             .attr('target', '_blank')
65338             .attr('tabindex', -1)
65339             .text('HDYC');
65340     }
65341
65342
65343     function displayChangeset(selection, entity) {
65344         if (!entity.changeset) {
65345             selection
65346                 .append('span')
65347                 .text(t('info_panels.history.unknown'));
65348             return;
65349         }
65350
65351         selection
65352             .append('span')
65353             .attr('class', 'changeset-id')
65354             .text(entity.changeset);
65355
65356         var links = selection
65357             .append('div')
65358             .attr('class', 'links');
65359
65360         if (osm) {
65361             links
65362                 .append('a')
65363                 .attr('class', 'changeset-osm-link')
65364                 .attr('href', osm.changesetURL(entity.changeset))
65365                 .attr('target', '_blank')
65366                 .attr('tabindex', -1)
65367                 .text('OSM');
65368         }
65369
65370         links
65371             .append('a')
65372             .attr('class', 'changeset-osmcha-link')
65373             .attr('href', 'https://osmcha.mapbox.com/changesets/' + entity.changeset)
65374             .attr('target', '_blank')
65375             .attr('tabindex', -1)
65376             .text('OSMCha');
65377     }
65378
65379
65380     function redraw(selection) {
65381         var selected = lodash.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
65382             singular = selected.length === 1 ? selected[0] : null;
65383
65384         osm = context.connection();
65385
65386         selection.html('');
65387
65388         selection
65389             .append('h4')
65390             .attr('class', 'history-heading')
65391             .text(singular || t('info_panels.history.selected', { n: selected.length }));
65392
65393         if (!singular) return;
65394
65395         var entity = context.entity(singular);
65396
65397         var list = selection
65398             .append('ul');
65399
65400         list
65401             .append('li')
65402             .text(t('info_panels.history.version') + ': ' + entity.version);
65403
65404         list
65405             .append('li')
65406             .text(t('info_panels.history.last_edit') + ': ' + displayTimestamp(entity));
65407
65408         list
65409             .append('li')
65410             .text(t('info_panels.history.edited_by') + ': ')
65411             .call(displayUser, entity);
65412
65413         list
65414             .append('li')
65415             .text(t('info_panels.history.changeset') + ': ')
65416             .call(displayChangeset, entity);
65417
65418         if (osm) {
65419             selection
65420                 .append('a')
65421                 .attr('class', 'view-history-on-osm')
65422                 .attr('target', '_blank')
65423                 .attr('tabindex', -1)
65424                 .attr('href', osm.historyURL(entity))
65425                 .call(svgIcon('#icon-out-link', 'inline'))
65426                 .append('span')
65427                 .text(t('info_panels.history.link_text'));
65428         }
65429     }
65430
65431
65432     var panel = function(selection) {
65433         selection.call(redraw);
65434
65435         context.map()
65436             .on('drawn.info-history', function() {
65437                 selection.call(redraw);
65438             });
65439     };
65440
65441     panel.off = function() {
65442         context.map()
65443             .on('drawn.info-history', null);
65444     };
65445
65446     panel.id = 'history';
65447     panel.title = t('info_panels.history.title');
65448     panel.key = t('info_panels.history.key');
65449
65450
65451     return panel;
65452 }
65453
65454 function uiPanelLocation(context) {
65455     var currLocation = '';
65456     var OSM_PRECISION = 7;
65457
65458
65459     function wrap(x, min, max) {
65460         var d = max - min;
65461         return ((x - min) % d + d) % d + min;
65462     }
65463
65464
65465     function clamp(x, min, max) {
65466         return Math.max(min, Math.min(x, max));
65467     }
65468
65469
65470     function redraw(selection) {
65471         selection.html('');
65472
65473         var list = selection
65474             .append('ul');
65475
65476         // Mouse coordinates
65477         var coord = context.map().mouseCoordinates();
65478         if (coord.some(isNaN)) {
65479             coord = context.map().center();
65480         }
65481
65482         var coordStr =
65483             clamp(coord[1], -90, 90).toFixed(OSM_PRECISION) + ', ' +
65484             wrap(coord[0], -180, 180).toFixed(OSM_PRECISION);
65485
65486         list
65487             .append('li')
65488             .text(coordStr);
65489
65490         // Location Info
65491         selection
65492             .append('div')
65493             .attr('class', 'location-info')
65494             .text(currLocation || ' ');
65495
65496         debouncedGetLocation(selection, coord);
65497     }
65498
65499
65500     var debouncedGetLocation = lodash.debounce(getLocation, 250);
65501     function getLocation(selection, coord) {
65502         if (!services.geocoder) {
65503             currLocation = t('info_panels.location.unknown_location');
65504             selection.selectAll('.location-info')
65505                 .text(currLocation);
65506         } else {
65507             services.geocoder.reverse(coord, function(err, result) {
65508                 currLocation = result ? result.display_name : t('info_panels.location.unknown_location');
65509                 selection.selectAll('.location-info')
65510                     .text(currLocation);
65511             });
65512         }
65513     }
65514
65515
65516     var panel = function(selection) {
65517         selection.call(redraw);
65518
65519         context.surface()
65520             .on('mousemove.info-location', function() {
65521                 selection.call(redraw);
65522             });
65523     };
65524
65525     panel.off = function() {
65526         context.surface()
65527             .on('mousemove.info-location', null);
65528     };
65529
65530     panel.id = 'location';
65531     panel.title = t('info_panels.location.title');
65532     panel.key = t('info_panels.location.key');
65533
65534
65535     return panel;
65536 }
65537
65538 function uiPanelMeasurement(context) {
65539     var isImperial = (utilDetect().locale.toLowerCase() === 'en-us');
65540     var OSM_PRECISION = 7;
65541
65542
65543     function radiansToMeters(r) {
65544         // using WGS84 authalic radius (6371007.1809 m)
65545         return r * 6371007.1809;
65546     }
65547
65548     function steradiansToSqmeters(r) {
65549         // http://gis.stackexchange.com/a/124857/40446
65550         return r / (4 * Math.PI) * 510065621724000;
65551     }
65552
65553
65554     function toLineString(feature) {
65555         if (feature.type === 'LineString') return feature;
65556
65557         var result = { type: 'LineString', coordinates: [] };
65558         if (feature.type === 'Polygon') {
65559             result.coordinates = feature.coordinates[0];
65560         } else if (feature.type === 'MultiPolygon') {
65561             result.coordinates = feature.coordinates[0][0];
65562         }
65563
65564         return result;
65565     }
65566
65567
65568     function displayLength(m) {
65569         var d = m * (isImperial ? 3.28084 : 1),
65570             p, unit;
65571
65572         if (isImperial) {
65573             if (d >= 5280) {
65574                 d /= 5280;
65575                 unit = 'mi';
65576             } else {
65577                 unit = 'ft';
65578             }
65579         } else {
65580             if (d >= 1000) {
65581                 d /= 1000;
65582                 unit = 'km';
65583             } else {
65584                 unit = 'm';
65585             }
65586         }
65587
65588         // drop unnecessary precision
65589         p = d > 1000 ? 0 : d > 100 ? 1 : 2;
65590
65591         return String(d.toFixed(p)) + ' ' + unit;
65592     }
65593
65594
65595     function displayArea(m2) {
65596         var d = m2 * (isImperial ? 10.7639111056 : 1),
65597             d1, d2, p1, p2, unit1, unit2;
65598
65599         if (isImperial) {
65600             if (d >= 6969600) {     // > 0.25mi² show mi²
65601                 d1 = d / 27878400;
65602                 unit1 = 'mi²';
65603             } else {
65604                 d1 = d;
65605                 unit1 = 'ft²';
65606             }
65607
65608             if (d > 4356 && d < 43560000) {   // 0.1 - 1000 acres
65609                 d2 = d / 43560;
65610                 unit2 = 'ac';
65611             }
65612
65613         } else {
65614             if (d >= 250000) {    // > 0.25km² show km²
65615                 d1 = d / 1000000;
65616                 unit1 = 'km²';
65617             } else {
65618                 d1 = d;
65619                 unit1 = 'm²';
65620             }
65621
65622             if (d > 1000 && d < 10000000) {   // 0.1 - 1000 hectares
65623                 d2 = d / 10000;
65624                 unit2 = 'ha';
65625             }
65626         }
65627
65628         // drop unnecessary precision
65629         p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
65630         p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
65631
65632         return String(d1.toFixed(p1)) + ' ' + unit1 +
65633             (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
65634     }
65635
65636
65637     function redraw(selection$$1) {
65638         var resolver = context.graph(),
65639             selected = lodash.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
65640             singular = selected.length === 1 ? selected[0] : null,
65641             extent$$1 = geoExtent$$1(),
65642             entity;
65643
65644         selection$$1.html('');
65645
65646         selection$$1
65647             .append('h4')
65648             .attr('class', 'measurement-heading')
65649             .text(singular || t('info_panels.measurement.selected', { n: selected.length }));
65650
65651         if (!selected.length) return;
65652
65653         var center;
65654         for (var i = 0; i < selected.length; i++) {
65655             entity = context.entity(selected[i]);
65656             extent$$1._extend(entity.extent(resolver));
65657         }
65658         center = extent$$1.center();
65659
65660
65661         var list = selection$$1
65662             .append('ul');
65663
65664         // multiple features, just display extent center..
65665         if (!singular) {
65666             list
65667                 .append('li')
65668                 .text(t('info_panels.measurement.center') + ': ' +
65669                     center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
65670                 );
65671             return;
65672         }
65673
65674         // single feature, display details..
65675         if (!entity) return;
65676         var geometry = entity.geometry(resolver);
65677
65678         if (geometry === 'line' || geometry === 'area') {
65679             var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
65680                 feature = entity.asGeoJSON(resolver),
65681                 length = radiansToMeters(d3GeoLength(toLineString(feature))),
65682                 lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
65683                 centroid = d3GeoCentroid(feature);
65684
65685             list
65686                 .append('li')
65687                 .text(t('info_panels.measurement.geometry') + ': ' +
65688                     (closed ? t('info_panels.measurement.closed') + ' ' : '') + t('geometry.' + geometry) );
65689
65690             if (closed) {
65691                 var area$$1 = steradiansToSqmeters(entity.area(resolver));
65692                 list
65693                     .append('li')
65694                     .text(t('info_panels.measurement.area') + ': ' + displayArea(area$$1));
65695             }
65696
65697             list
65698                 .append('li')
65699                 .text(lengthLabel + ': ' + displayLength(length));
65700
65701             list
65702                 .append('li')
65703                 .text(t('info_panels.measurement.centroid') + ': ' +
65704                     centroid[1].toFixed(OSM_PRECISION) + ', ' + centroid[0].toFixed(OSM_PRECISION)
65705                 );
65706
65707
65708             var toggle  = isImperial ? 'imperial' : 'metric';
65709
65710             selection$$1
65711                 .append('a')
65712                 .text(t('info_panels.measurement.' + toggle))
65713                 .attr('href', '#')
65714                 .attr('class', 'button button-toggle-units')
65715                 .on('click', function() {
65716                     event.preventDefault();
65717                     isImperial = !isImperial;
65718                     selection$$1.call(redraw);
65719                 });
65720
65721         } else {
65722             var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));
65723
65724             list
65725                 .append('li')
65726                 .text(t('info_panels.measurement.geometry') + ': ' + t('geometry.' + geometry));
65727
65728             list
65729                 .append('li')
65730                 .text(centerLabel + ': ' +
65731                     center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
65732                 );
65733         }
65734     }
65735
65736
65737     var panel = function(selection$$1) {
65738         selection$$1.call(redraw);
65739
65740         context.map()
65741             .on('drawn.info-measurement', function() {
65742                 selection$$1.call(redraw);
65743             });
65744     };
65745
65746     panel.off = function() {
65747         context.map()
65748             .on('drawn.info-measurement', null);
65749     };
65750
65751     panel.id = 'measurement';
65752     panel.title = t('info_panels.measurement.title');
65753     panel.key = t('info_panels.measurement.key');
65754
65755
65756     return panel;
65757 }
65758
65759 var uiInfoPanels = {
65760     background: uiPanelBackground,
65761     history: uiPanelHistory,
65762     location: uiPanelLocation,
65763     measurement: uiPanelMeasurement,
65764 };
65765
65766 function uiInfo(context) {
65767     var ids = Object.keys(uiInfoPanels),
65768         wasActive = ['measurement'],
65769         panels = {},
65770         active$$1 = {};
65771
65772     // create panels
65773     ids.forEach(function(k) {
65774         if (!panels[k]) {
65775             panels[k] = uiInfoPanels[k](context);
65776             active$$1[k] = false;
65777         }
65778     });
65779
65780
65781     function info(selection$$1) {
65782
65783         function redraw() {
65784             var activeids = ids.filter(function(k) { return active$$1[k]; }).sort();
65785
65786             var containers = infoPanels.selectAll('.panel-container')
65787                 .data(activeids, function(k) { return k; });
65788
65789             containers.exit()
65790                 .style('opacity', 1)
65791                 .transition()
65792                 .duration(200)
65793                 .style('opacity', 0)
65794                 .on('end', function(d) {
65795                     select(this)
65796                         .call(panels[d].off)
65797                         .remove();
65798                 });
65799
65800             var enter = containers.enter()
65801                 .append('div')
65802                 .attr('class', function(d) { return 'fillD2 panel-container panel-container-' + d; });
65803
65804             enter
65805                 .style('opacity', 0)
65806                 .transition()
65807                 .duration(200)
65808                 .style('opacity', 1);
65809
65810             var title = enter
65811                 .append('div')
65812                 .attr('class', 'panel-title fillD2');
65813
65814             title
65815                 .append('h3')
65816                 .text(function(d) { return panels[d].title; });
65817
65818             title
65819                 .append('button')
65820                 .attr('class', 'close')
65821                 .on('click', function (d) { toggle(d); })
65822                 .call(svgIcon('#icon-close'));
65823
65824             enter
65825                 .append('div')
65826                 .attr('class', function(d) { return 'panel-content panel-content-' + d; });
65827
65828
65829             // redraw the panels
65830             infoPanels.selectAll('.panel-content')
65831                 .each(function(d) {
65832                     select(this).call(panels[d]);
65833                 });
65834         }
65835
65836
65837         function toggle(which) {
65838             if (event) {
65839                 event.stopImmediatePropagation();
65840                 event.preventDefault();
65841             }
65842
65843             var activeids = ids.filter(function(k) { return active$$1[k]; });
65844
65845             if (which) {  // toggle one
65846                 active$$1[which] = !active$$1[which];
65847                 if (activeids.length === 1 && activeids[0] === which) {  // none active anymore
65848                     wasActive = [which];
65849                 }
65850             } else {      // toggle all
65851                 if (activeids.length) {
65852                     wasActive = activeids;
65853                     activeids.forEach(function(k) { active$$1[k] = false; });
65854                 } else {
65855                     wasActive.forEach(function(k) { active$$1[k] = true; });
65856                 }
65857             }
65858
65859             redraw();
65860         }
65861
65862
65863         var infoPanels = selection$$1.selectAll('.info-panels')
65864             .data([0]);
65865
65866         infoPanels = infoPanels.enter()
65867             .append('div')
65868             .attr('class', 'info-panels')
65869             .merge(infoPanels);
65870
65871         redraw();
65872
65873         var keybinding = d3keybinding('info')
65874             .on(uiCmd('⌘' + t('info_panels.key')), toggle);
65875
65876         ids.forEach(function(k) {
65877             var key = t('info_panels.' + k + '.key', { default: null });
65878             if (!key) return;
65879             keybinding
65880                 .on(uiCmd('⌘⇧' + key), function() { toggle(k); });
65881         });
65882
65883         select(document)
65884             .call(keybinding);
65885     }
65886
65887     return info;
65888 }
65889
65890 function uiMapData(context) {
65891     var key = t('map_data.key'),
65892         features = context.features().keys(),
65893         layers = context.layers(),
65894         fills = ['wireframe', 'partial', 'full'],
65895         fillDefault = context.storage('area-fill') || 'partial',
65896         fillSelected = fillDefault;
65897
65898
65899     function map_data(selection$$1) {
65900
65901         function showsFeature(d) {
65902             return context.features().enabled(d);
65903         }
65904
65905
65906         function autoHiddenFeature(d) {
65907             return context.features().autoHidden(d);
65908         }
65909
65910
65911         function clickFeature(d) {
65912             context.features().toggle(d);
65913             update();
65914         }
65915
65916
65917         function showsFill(d) {
65918             return fillSelected === d;
65919         }
65920
65921
65922         function setFill(d) {
65923             lodash.each(fills, function(opt) {
65924                 context.surface().classed('fill-' + opt, Boolean(opt === d));
65925             });
65926
65927             fillSelected = d;
65928             if (d !== 'wireframe') {
65929                 fillDefault = d;
65930                 context.storage('area-fill', d);
65931             }
65932             update();
65933         }
65934
65935
65936         function showsLayer(which) {
65937             var layer = layers.layer(which);
65938             if (layer) {
65939                 return layer.enabled();
65940             }
65941             return false;
65942         }
65943
65944
65945         function setLayer(which, enabled) {
65946             var layer = layers.layer(which);
65947             if (layer) {
65948                 layer.enabled(enabled);
65949                 update();
65950             }
65951         }
65952
65953
65954         function toggleLayer(which) {
65955             setLayer(which, !showsLayer(which));
65956         }
65957
65958
65959         function clickGpx() {
65960             toggleLayer('gpx');
65961         }
65962
65963
65964         function clickMapillaryImages() {
65965             toggleLayer('mapillary-images');
65966             if (!showsLayer('mapillary-images')) {
65967                 setLayer('mapillary-signs', false);
65968             }
65969         }
65970
65971
65972         function clickMapillarySigns() {
65973             toggleLayer('mapillary-signs');
65974         }
65975
65976
65977         function drawMapillaryItems(selection$$1) {
65978             var mapillaryImages = layers.layer('mapillary-images'),
65979                 mapillarySigns = layers.layer('mapillary-signs'),
65980                 supportsMapillaryImages = mapillaryImages && mapillaryImages.supported(),
65981                 supportsMapillarySigns = mapillarySigns && mapillarySigns.supported(),
65982                 showsMapillaryImages = supportsMapillaryImages && mapillaryImages.enabled(),
65983                 showsMapillarySigns = supportsMapillarySigns && mapillarySigns.enabled();
65984
65985             var mapillaryList = selection$$1
65986                 .selectAll('.layer-list-mapillary')
65987                 .data([0]);
65988
65989             mapillaryList = mapillaryList.enter()
65990                 .append('ul')
65991                 .attr('class', 'layer-list layer-list-mapillary')
65992                 .merge(mapillaryList);
65993
65994
65995             var mapillaryImageLayerItem = mapillaryList
65996                 .selectAll('.list-item-mapillary-images')
65997                 .data(supportsMapillaryImages ? [0] : []);
65998
65999             mapillaryImageLayerItem.exit()
66000                 .remove();
66001
66002             var enterImages = mapillaryImageLayerItem.enter()
66003                 .append('li')
66004                 .attr('class', 'list-item-mapillary-images');
66005
66006             var labelImages = enterImages
66007                 .append('label')
66008                 .call(tooltip()
66009                     .title(t('mapillary_images.tooltip'))
66010                     .placement('top'));
66011
66012             labelImages
66013                 .append('input')
66014                 .attr('type', 'checkbox')
66015                 .on('change', clickMapillaryImages);
66016
66017             labelImages
66018                 .append('span')
66019                 .text(t('mapillary_images.title'));
66020
66021
66022             var mapillarySignLayerItem = mapillaryList
66023                 .selectAll('.list-item-mapillary-signs')
66024                 .data(supportsMapillarySigns ? [0] : []);
66025
66026             mapillarySignLayerItem.exit()
66027                 .remove();
66028
66029             var enterSigns = mapillarySignLayerItem.enter()
66030                 .append('li')
66031                 .attr('class', 'list-item-mapillary-signs');
66032
66033             var labelSigns = enterSigns
66034                 .append('label')
66035                 .call(tooltip()
66036                     .title(t('mapillary_signs.tooltip'))
66037                     .placement('top'));
66038
66039             labelSigns
66040                 .append('input')
66041                 .attr('type', 'checkbox')
66042                 .on('change', clickMapillarySigns);
66043
66044             labelSigns
66045                 .append('span')
66046                 .text(t('mapillary_signs.title'));
66047
66048
66049             // Updates
66050             mapillaryImageLayerItem = mapillaryImageLayerItem
66051                 .merge(enterImages);
66052
66053             mapillaryImageLayerItem
66054                 .classed('active', showsMapillaryImages)
66055                 .selectAll('input')
66056                 .property('checked', showsMapillaryImages);
66057
66058
66059             mapillarySignLayerItem = mapillarySignLayerItem
66060                 .merge(enterSigns);
66061
66062             mapillarySignLayerItem
66063                 .classed('active', showsMapillarySigns)
66064                 .selectAll('input')
66065                 .property('disabled', !showsMapillaryImages)
66066                 .property('checked', showsMapillarySigns);
66067
66068             mapillarySignLayerItem
66069                 .selectAll('label')
66070                 .classed('deemphasize', !showsMapillaryImages);
66071         }
66072
66073
66074         function drawGpxItem(selection$$1) {
66075             var gpx = layers.layer('gpx'),
66076                 hasGpx = gpx && gpx.hasGpx(),
66077                 showsGpx = hasGpx && gpx.enabled();
66078
66079             var gpxLayerItem = selection$$1
66080                 .selectAll('.layer-list-gpx')
66081                 .data(gpx ? [0] : []);
66082
66083             // Exit
66084             gpxLayerItem.exit()
66085                 .remove();
66086
66087             // Enter
66088             var enter = gpxLayerItem.enter()
66089                 .append('ul')
66090                 .attr('class', 'layer-list layer-list-gpx')
66091                 .append('li')
66092                 .classed('list-item-gpx', true);
66093
66094             enter
66095                 .append('button')
66096                 .attr('class', 'list-item-gpx-extent')
66097                 .call(tooltip()
66098                     .title(t('gpx.zoom'))
66099                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
66100                 .on('click', function() {
66101                     event.preventDefault();
66102                     event.stopPropagation();
66103                     gpx.fitZoom();
66104                 })
66105                 .call(svgIcon('#icon-search'));
66106
66107             enter
66108                 .append('button')
66109                 .attr('class', 'list-item-gpx-browse')
66110                 .call(tooltip()
66111                     .title(t('gpx.browse'))
66112                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
66113                 .on('click', function() {
66114                     select(document.createElement('input'))
66115                         .attr('type', 'file')
66116                         .on('change', function() {
66117                             gpx.files(event.target.files);
66118                         })
66119                         .node().click();
66120                 })
66121                 .call(svgIcon('#icon-geolocate'));
66122
66123             var labelGpx = enter
66124                 .append('label')
66125                 .call(tooltip().title(t('gpx.drag_drop')).placement('top'));
66126
66127             labelGpx
66128                 .append('input')
66129                 .attr('type', 'checkbox')
66130                 .on('change', clickGpx);
66131
66132             labelGpx
66133                 .append('span')
66134                 .text(t('gpx.local_layer'));
66135
66136
66137             // Update
66138             gpxLayerItem = gpxLayerItem
66139                 .merge(enter);
66140
66141             gpxLayerItem
66142                 .classed('active', showsGpx)
66143                 .selectAll('input')
66144                 .property('disabled', !hasGpx)
66145                 .property('checked', showsGpx);
66146
66147             gpxLayerItem
66148                 .selectAll('label')
66149                 .classed('deemphasize', !hasGpx);
66150         }
66151
66152
66153         function drawList(selection$$1, data, type, name, change, active$$1) {
66154             var items = selection$$1.selectAll('li')
66155                 .data(data);
66156
66157             // Exit
66158             items.exit()
66159                 .remove();
66160
66161             // Enter
66162             var enter = items.enter()
66163                 .append('li')
66164                 .attr('class', 'layer')
66165                 .call(tooltip()
66166                     .html(true)
66167                     .title(function(d) {
66168                         var tip = t(name + '.' + d + '.tooltip'),
66169                             key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null);
66170
66171                         if (name === 'feature' && autoHiddenFeature(d)) {
66172                             tip += '<div>' + t('map_data.autohidden') + '</div>';
66173                         }
66174                         return uiTooltipHtml(tip, key);
66175                     })
66176                     .placement('top')
66177                 );
66178
66179             var label = enter
66180                 .append('label');
66181
66182             label
66183                 .append('input')
66184                 .attr('type', type)
66185                 .attr('name', name)
66186                 .on('change', change);
66187
66188             label
66189                 .append('span')
66190                 .text(function(d) { return t(name + '.' + d + '.description'); });
66191
66192             // Update
66193             items = items
66194                 .merge(enter);
66195
66196             items
66197                 .classed('active', active$$1)
66198                 .selectAll('input')
66199                 .property('checked', active$$1)
66200                 .property('indeterminate', function(d) {
66201                     return (name === 'feature' && autoHiddenFeature(d));
66202                 });
66203         }
66204
66205
66206         function update() {
66207             dataLayerContainer.call(drawMapillaryItems);
66208             dataLayerContainer.call(drawGpxItem);
66209
66210             fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);
66211             featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
66212         }
66213
66214
66215         function hidePanel() {
66216             setVisible(false);
66217         }
66218
66219
66220         function togglePanel() {
66221             if (event) event.preventDefault();
66222             tooltipBehavior.hide(button);
66223             setVisible(!button.classed('active'));
66224         }
66225
66226
66227         function toggleWireframe() {
66228             if (event) {
66229                 event.preventDefault();
66230                 event.stopPropagation();
66231             }
66232             setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
66233             context.map().pan([0,0]);  // trigger a redraw
66234         }
66235
66236
66237         function setVisible(show) {
66238             if (show !== shown) {
66239                 button.classed('active', show);
66240                 shown = show;
66241
66242                 if (show) {
66243                     update();
66244                     selection$$1.on('mousedown.map_data-inside', function() {
66245                         return event.stopPropagation();
66246                     });
66247                     content.style('display', 'block')
66248                         .style('right', '-300px')
66249                         .transition()
66250                         .duration(200)
66251                         .style('right', '0px');
66252                 } else {
66253                     content.style('display', 'block')
66254                         .style('right', '0px')
66255                         .transition()
66256                         .duration(200)
66257                         .style('right', '-300px')
66258                         .on('end', function() {
66259                             select(this).style('display', 'none');
66260                         });
66261                     selection$$1.on('mousedown.map_data-inside', null);
66262                 }
66263             }
66264         }
66265
66266
66267         var content = selection$$1
66268                 .append('div')
66269                 .attr('class', 'fillL map-overlay col3 content hide'),
66270             tooltipBehavior = tooltip()
66271                 .placement((textDirection === 'rtl') ? 'right' : 'left')
66272                 .html(true)
66273                 .title(uiTooltipHtml(t('map_data.description'), key)),
66274             button = selection$$1
66275                 .append('button')
66276                 .attr('tabindex', -1)
66277                 .on('click', togglePanel)
66278                 .call(svgIcon('#icon-data', 'light'))
66279                 .call(tooltipBehavior),
66280             shown = false;
66281
66282         content
66283             .append('h4')
66284             .text(t('map_data.title'));
66285
66286
66287         // data layers
66288         content
66289             .append('a')
66290             .text(t('map_data.data_layers'))
66291             .attr('href', '#')
66292             .classed('hide-toggle', true)
66293             .classed('expanded', true)
66294             .on('click', function() {
66295                 var exp = select(this).classed('expanded');
66296                 dataLayerContainer.style('display', exp ? 'none' : 'block');
66297                 select(this).classed('expanded', !exp);
66298                 event.preventDefault();
66299             });
66300
66301         var dataLayerContainer = content
66302             .append('div')
66303             .attr('class', 'data-data-layers')
66304             .style('display', 'block');
66305
66306
66307         // area fills
66308         content
66309             .append('a')
66310             .text(t('map_data.fill_area'))
66311             .attr('href', '#')
66312             .classed('hide-toggle', true)
66313             .classed('expanded', false)
66314             .on('click', function() {
66315                 var exp = select(this).classed('expanded');
66316                 fillContainer.style('display', exp ? 'none' : 'block');
66317                 select(this).classed('expanded', !exp);
66318                 event.preventDefault();
66319             });
66320
66321         var fillContainer = content
66322             .append('div')
66323             .attr('class', 'data-area-fills')
66324             .style('display', 'none');
66325
66326         var fillList = fillContainer
66327             .append('ul')
66328             .attr('class', 'layer-list layer-fill-list');
66329
66330
66331         // feature filters
66332         content
66333             .append('a')
66334             .text(t('map_data.map_features'))
66335             .attr('href', '#')
66336             .classed('hide-toggle', true)
66337             .classed('expanded', false)
66338             .on('click', function() {
66339                 var exp = select(this).classed('expanded');
66340                 featureContainer.style('display', exp ? 'none' : 'block');
66341                 select(this).classed('expanded', !exp);
66342                 event.preventDefault();
66343             });
66344
66345         var featureContainer = content
66346             .append('div')
66347             .attr('class', 'data-feature-filters')
66348             .style('display', 'none');
66349
66350         var featureList = featureContainer
66351             .append('ul')
66352             .attr('class', 'layer-list layer-feature-list');
66353
66354
66355         context.features()
66356             .on('change.map_data-update', update);
66357
66358         setFill(fillDefault);
66359
66360         var keybinding = d3keybinding('features')
66361             .on(key, togglePanel)
66362             .on(t('area_fill.wireframe.key'), toggleWireframe)
66363             .on([t('background.key'), t('help.key')], hidePanel);
66364
66365         select(document)
66366             .call(keybinding);
66367
66368         context.surface().on('mousedown.map_data-outside', hidePanel);
66369         context.container().on('mousedown.map_data-outside', hidePanel);
66370     }
66371
66372
66373     return map_data;
66374 }
66375
66376 function uiModes(context) {
66377     var modes = [
66378         modeAddPoint$$1(context),
66379         modeAddLine$$1(context),
66380         modeAddArea$$1(context)
66381     ];
66382
66383
66384     function editable() {
66385         return context.editable() && context.mode().id !== 'save';
66386     }
66387
66388
66389     return function(selection$$1) {
66390         var buttons = selection$$1.selectAll('button.add-button')
66391             .data(modes);
66392
66393         buttons = buttons.enter()
66394             .append('button')
66395             .attr('tabindex', -1)
66396             .attr('class', function(mode) { return mode.id + ' add-button col4'; })
66397             .on('click.mode-buttons', function(mode) {
66398                 // When drawing, ignore accidental clicks on mode buttons - #4042
66399                 var currMode = context.mode().id;
66400                 if (currMode.match(/^draw/) !== null) return;
66401
66402                 if (mode.id === currMode) {
66403                     context.enter(modeBrowse(context));
66404                 } else {
66405                     context.enter(mode);
66406                 }
66407             })
66408             .call(tooltip()
66409                 .placement('bottom')
66410                 .html(true)
66411                 .title(function(mode) {
66412                     return uiTooltipHtml(mode.description, mode.key);
66413                 })
66414             );
66415
66416         context.map()
66417             .on('move.modes', lodash.debounce(update, 500));
66418
66419         context
66420             .on('enter.modes', update);
66421
66422         buttons
66423             .each(function(d) {
66424                 select(this)
66425                     .call(svgIcon('#icon-' + d.button, 'pre-text'));
66426             });
66427
66428         buttons
66429             .append('span')
66430             .attr('class', 'label')
66431             .text(function(mode) { return mode.title; });
66432
66433         context
66434             .on('enter.editor', function(entered) {
66435                 selection$$1.selectAll('button.add-button')
66436                     .classed('active', function(mode) { return entered.button === mode.button; });
66437                 context.container()
66438                     .classed('mode-' + entered.id, true);
66439             });
66440
66441         context
66442             .on('exit.editor', function(exited) {
66443                 context.container()
66444                     .classed('mode-' + exited.id, false);
66445             });
66446
66447         var keybinding = d3keybinding('mode-buttons');
66448
66449         modes.forEach(function(mode) {
66450             keybinding.on(mode.key, function() {
66451                 if (editable()) {
66452                     if (mode.id === context.mode().id) {
66453                         context.enter(modeBrowse(context));
66454                     } else {
66455                         context.enter(mode);
66456                     }
66457                 }
66458             });
66459         });
66460
66461         select(document)
66462             .call(keybinding);
66463
66464
66465         function update() {
66466             selection$$1.selectAll('button.add-button')
66467                 .property('disabled', !editable());
66468         }
66469     };
66470 }
66471
66472 function uiRestore(context) {
66473
66474     return function(selection) {
66475         if (!context.history().lock() || !context.history().restorableChanges())
66476             return;
66477
66478         var modalSelection = uiModal(selection, true);
66479
66480         modalSelection.select('.modal')
66481             .attr('class', 'modal fillL col6');
66482
66483         var introModal = modalSelection.select('.content');
66484
66485         introModal
66486             .attr('class','cf');
66487
66488         introModal
66489             .append('div')
66490             .attr('class', 'modal-section')
66491             .append('h3')
66492             .text(t('restore.heading'));
66493
66494         introModal
66495             .append('div')
66496             .attr('class','modal-section')
66497             .append('p')
66498             .text(t('restore.description'));
66499
66500         var buttonWrap = introModal
66501             .append('div')
66502             .attr('class', 'modal-actions cf');
66503
66504         var restore = buttonWrap
66505             .append('button')
66506             .attr('class', 'restore col6')
66507             .on('click', function() {
66508                 context.history().restore();
66509                 modalSelection.remove();
66510             });
66511
66512         restore
66513             .append('svg')
66514             .attr('class', 'logo logo-restore')
66515             .append('use')
66516             .attr('xlink:href', '#logo-restore');
66517
66518         restore
66519             .append('div')
66520             .text(t('restore.restore'));
66521
66522         var reset = buttonWrap
66523             .append('button')
66524             .attr('class', 'reset col6')
66525             .on('click', function() {
66526                 context.history().clearSaved();
66527                 modalSelection.remove();
66528             });
66529
66530         reset
66531             .append('svg')
66532             .attr('class', 'logo logo-reset')
66533             .append('use')
66534             .attr('xlink:href', '#logo-reset');
66535
66536         reset
66537             .append('div')
66538             .text(t('restore.reset'));
66539
66540         restore.node().focus();
66541     };
66542 }
66543
66544 function uiSave(context) {
66545     var history = context.history(),
66546         key = uiCmd('⌘S');
66547
66548
66549     function saving() {
66550         return context.mode().id === 'save';
66551     }
66552
66553
66554     function save() {
66555         event.preventDefault();
66556         if (!context.inIntro() && !saving() && history.hasChanges()) {
66557             context.enter(modeSave$$1(context));
66558         }
66559     }
66560
66561
66562     function getBackground(numChanges) {
66563         var step$$1;
66564         if (numChanges === 0) {
66565             return null;
66566         } else if (numChanges <= 50) {
66567             step$$1 = numChanges / 50;
66568             return interpolateRgb('#fff', '#ff8')(step$$1);  // white -> yellow
66569         } else {
66570             step$$1 = Math.min((numChanges - 50) / 50, 1.0);
66571             return interpolateRgb('#ff8', '#f88')(step$$1);  // yellow -> red
66572         }
66573     }
66574
66575
66576     return function(selection$$1) {
66577         var numChanges = 0;
66578
66579         function updateCount() {
66580             var _ = history.difference().summary().length;
66581             if (_ === numChanges) return;
66582             numChanges = _;
66583
66584             tooltipBehavior
66585                 .title(uiTooltipHtml(
66586                     t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key)
66587                 );
66588
66589             var background = getBackground(numChanges);
66590
66591             button
66592                 .classed('disabled', numChanges === 0)
66593                 .classed('has-count', numChanges > 0)
66594                 .style('background', background);
66595
66596             button.select('span.count')
66597                 .text(numChanges)
66598                 .style('background', background)
66599                 .style('border-color', background);
66600         }
66601
66602
66603         var tooltipBehavior = tooltip()
66604             .placement('bottom')
66605             .html(true)
66606             .title(uiTooltipHtml(t('save.no_changes'), key));
66607
66608         var button = selection$$1
66609             .append('button')
66610             .attr('class', 'save col12 disabled')
66611             .attr('tabindex', -1)
66612             .on('click', save)
66613             .call(tooltipBehavior);
66614
66615         button
66616             .call(svgIcon('#icon-save', 'pre-text'))
66617             .append('span')
66618             .attr('class', 'label')
66619             .text(t('save.title'));
66620
66621         button
66622             .append('span')
66623             .attr('class', 'count')
66624             .text('0');
66625
66626         updateCount();
66627
66628
66629         var keybinding = d3keybinding('save')
66630             .on(key, save, true);
66631
66632         select(document)
66633             .call(keybinding);
66634
66635         context.history()
66636             .on('change.save', updateCount);
66637
66638         context
66639             .on('enter.save', function() {
66640                 button.property('disabled', saving());
66641                 if (saving()) button.call(tooltipBehavior.hide);
66642             });
66643     };
66644 }
66645
66646 function uiScale(context) {
66647     var projection = context.projection,
66648         isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
66649         maxLength = 180,
66650         tickHeight = 8;
66651
66652
66653     function scaleDefs(loc1, loc2) {
66654         var lat = (loc2[1] + loc1[1]) / 2,
66655             conversion = (isImperial ? 3.28084 : 1),
66656             dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
66657             scale = { dist: 0, px: 0, text: '' },
66658             buckets, i, val, dLon;
66659
66660         if (isImperial) {
66661             buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
66662         } else {
66663             buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
66664         }
66665
66666         // determine a user-friendly endpoint for the scale
66667         for (i = 0; i < buckets.length; i++) {
66668             val = buckets[i];
66669             if (dist >= val) {
66670                 scale.dist = Math.floor(dist / val) * val;
66671                 break;
66672             } else {
66673                 scale.dist = +dist.toFixed(2);
66674             }
66675         }
66676
66677         dLon = geoMetersToLon(scale.dist / conversion, lat);
66678         scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
66679
66680         if (isImperial) {
66681             if (scale.dist >= 5280) {
66682                 scale.dist /= 5280;
66683                 scale.text = String(scale.dist) + ' mi';
66684             } else {
66685                 scale.text = String(scale.dist) + ' ft';
66686             }
66687         } else {
66688             if (scale.dist >= 1000) {
66689                 scale.dist /= 1000;
66690                 scale.text = String(scale.dist) + ' km';
66691             } else {
66692                 scale.text = String(scale.dist) + ' m';
66693             }
66694         }
66695
66696         return scale;
66697     }
66698
66699
66700     function update(selection) {
66701         // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
66702         var dims = context.map().dimensions(),
66703             loc1 = projection.invert([0, dims[1]]),
66704             loc2 = projection.invert([maxLength, dims[1]]),
66705             scale = scaleDefs(loc1, loc2);
66706
66707         selection.select('#scale-path')
66708             .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
66709
66710         selection.select('#scale-textgroup')
66711             .attr('transform', 'translate(' + (scale.px + 8) + ',' + tickHeight + ')');
66712
66713         selection.select('#scale-text')
66714             .text(scale.text);
66715     }
66716
66717
66718     return function(selection) {
66719         function switchUnits() {
66720             isImperial = !isImperial;
66721             selection.call(update);
66722         }
66723
66724         var scalegroup = selection.append('svg')
66725             .attr('id', 'scale')
66726             .on('click', switchUnits)
66727             .append('g')
66728             .attr('transform', 'translate(10,11)');
66729
66730         scalegroup
66731             .append('path')
66732             .attr('id', 'scale-path');
66733
66734         scalegroup
66735             .append('g')
66736             .attr('id', 'scale-textgroup')
66737             .append('text')
66738             .attr('id', 'scale-text');
66739
66740         selection.call(update);
66741
66742         context.map().on('move.scale', function() {
66743             update(selection);
66744         });
66745     };
66746 }
66747
66748 var pair_1 = pair$1;
66749 function search(x, dims, r) {
66750   if (!dims) dims = 'NSEW';
66751   if (typeof x !== 'string') return { val: null, regex: r };
66752
66753   r = r || /[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)°?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/gi;
66754
66755   var m = r.exec(x);
66756   if (!m) return { val: null, regex: r };
66757
66758   var dim = m[1] || m[5];
66759   if (dim && dims.indexOf(dim) === -1) return { val: null, regex: r };
66760
66761   return {
66762     val: (((m[2]) ? parseFloat(m[2]) : 0) +
66763           ((m[3] ? parseFloat(m[3]) / 60 : 0)) +
66764           ((m[4] ? parseFloat(m[4]) / 3600 : 0))) *
66765           ((dim === 'S' || dim === 'W') ? -1 : 1),
66766     regex: r,
66767     raw: m[0],
66768     dim: dim
66769   };
66770 }
66771
66772 function pair$1(x, dims) {
66773   x = x.trim();
66774   var one = search(x, dims);
66775   if (one.val === null) return null;
66776   var two = search(x, dims, one.regex);
66777   if (two.val === null) return null;
66778   // null if one/two are not contiguous.
66779   if (one.raw + two.raw !== x) return null;
66780   if (one.dim) {
66781     return swapdim(one.val, two.val, one.dim);
66782   } else {
66783     return [one.val, two.val];
66784   }
66785 }
66786
66787 function swapdim(a, b, dim) {
66788   if (dim === 'N' || dim === 'S') return [a, b];
66789   if (dim === 'W' || dim === 'E') return [b, a];
66790 }
66791
66792 function uiFeatureList(context) {
66793     var geocodeResults;
66794
66795
66796     function featureList(selection$$1) {
66797         var header = selection$$1
66798             .append('div')
66799             .attr('class', 'header fillL cf');
66800
66801         header.append('h3')
66802             .text(t('inspector.feature_list'));
66803
66804         var searchWrap = selection$$1
66805             .append('div')
66806             .attr('class', 'search-header');
66807
66808         var search = searchWrap
66809             .append('input')
66810             .attr('placeholder', t('inspector.search'))
66811             .attr('type', 'search')
66812             .call(utilNoAuto)
66813             .on('keypress', keypress)
66814             .on('input', inputevent);
66815
66816         searchWrap
66817             .call(svgIcon('#icon-search', 'pre-text'));
66818
66819         var listWrap = selection$$1
66820             .append('div')
66821             .attr('class', 'inspector-body');
66822
66823         var list = listWrap
66824             .append('div')
66825             .attr('class', 'feature-list cf');
66826
66827         context
66828             .on('exit.feature-list', clearSearch);
66829         context.map()
66830             .on('drawn.feature-list', mapDrawn);
66831
66832
66833         function keypress() {
66834             var q = search.property('value'),
66835                 items = list.selectAll('.feature-list-item');
66836             if (event.keyCode === 13 && q.length && items.size()) {
66837                 click(items.datum());
66838             }
66839         }
66840
66841
66842         function inputevent() {
66843             geocodeResults = undefined;
66844             drawList();
66845         }
66846
66847
66848         function clearSearch() {
66849             search.property('value', '');
66850             drawList();
66851         }
66852
66853
66854         function mapDrawn(e) {
66855             if (e.full) {
66856                 drawList();
66857             }
66858         }
66859
66860
66861         function features() {
66862             var entities = {},
66863                 result = [],
66864                 graph = context.graph(),
66865                 q = search.property('value').toLowerCase();
66866
66867             if (!q) return result;
66868
66869             var idMatch = q.match(/^([nwr])([0-9]+)$/);
66870
66871             if (idMatch) {
66872                 result.push({
66873                     id: idMatch[0],
66874                     geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
66875                     type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
66876                     name: idMatch[2]
66877                 });
66878             }
66879
66880             var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
66881
66882             if (locationMatch) {
66883                 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
66884                 result.push({
66885                     id: -1,
66886                     geometry: 'point',
66887                     type: t('inspector.location'),
66888                     name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
66889                     location: loc
66890                 });
66891             }
66892
66893             function addEntity(entity) {
66894                 if (entity.id in entities || result.length > 200)
66895                     return;
66896
66897                 entities[entity.id] = true;
66898
66899                 var name = utilDisplayName(entity) || '';
66900                 if (name.toLowerCase().indexOf(q) >= 0) {
66901                     var matched = context.presets().match(entity, graph),
66902                         type = (matched && matched.name()) || utilDisplayType(entity.id);
66903                     result.push({
66904                         id: entity.id,
66905                         entity: entity,
66906                         geometry: context.geometry(entity.id),
66907                         type: type,
66908                         name: name
66909                     });
66910                 }
66911
66912                 graph.parentRelations(entity).forEach(function(parent) {
66913                     addEntity(parent);
66914                 });
66915             }
66916
66917             var visible = context.surface().selectAll('.point, .line, .area').nodes();
66918             for (var i = 0; i < visible.length && result.length <= 200; i++) {
66919                 addEntity(visible[i].__data__);
66920             }
66921
66922             (geocodeResults || []).forEach(function(d) {
66923                 // https://github.com/openstreetmap/iD/issues/1890
66924                 if (d.osm_type && d.osm_id) {
66925                     result.push({
66926                         id: osmEntity$$1.id.fromOSM(d.osm_type, d.osm_id),
66927                         geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
66928                         type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
66929                                                : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
66930                         name: d.display_name,
66931                         extent: new geoExtent$$1(
66932                             [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
66933                             [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
66934                     });
66935                 }
66936             });
66937
66938             return result;
66939         }
66940
66941
66942         function drawList() {
66943             var value = search.property('value'),
66944                 results = features();
66945
66946             list.classed('filtered', value.length);
66947
66948             var noResultsWorldwide = geocodeResults && geocodeResults.length === 0;
66949
66950             var resultsIndicator = list.selectAll('.no-results-item')
66951                 .data([0])
66952                 .enter().append('button')
66953                 .property('disabled', true)
66954                 .attr('class', 'no-results-item')
66955                 .call(svgIcon('#icon-alert', 'pre-text'));
66956
66957             resultsIndicator.append('span')
66958                 .attr('class', 'entity-name');
66959
66960             list.selectAll('.no-results-item .entity-name')
66961                 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
66962
66963             if (services.geocoder) {
66964               list.selectAll('.geocode-item')
66965                   .data([0])
66966                   .enter().append('button')
66967                   .attr('class', 'geocode-item')
66968                   .on('click', geocoderSearch)
66969                   .append('div')
66970                   .attr('class', 'label')
66971                   .append('span')
66972                   .attr('class', 'entity-name')
66973                   .text(t('geocoder.search'));
66974             }
66975
66976             list.selectAll('.no-results-item')
66977                 .style('display', (value.length && !results.length) ? 'block' : 'none');
66978
66979             list.selectAll('.geocode-item')
66980                 .style('display', (value && geocodeResults === undefined) ? 'block' : 'none');
66981
66982             list.selectAll('.feature-list-item')
66983                 .data([-1])
66984                 .remove();
66985
66986             var items = list.selectAll('.feature-list-item')
66987                 .data(results, function(d) { return d.id; });
66988
66989             var enter = items.enter()
66990                 .insert('button', '.geocode-item')
66991                 .attr('class', 'feature-list-item')
66992                 .on('mouseover', mouseover)
66993                 .on('mouseout', mouseout)
66994                 .on('click', click);
66995
66996             var label = enter
66997                 .append('div')
66998                 .attr('class', 'label');
66999
67000             label.each(function(d) {
67001                 select(this)
67002                     .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
67003             });
67004
67005             label.append('span')
67006                 .attr('class', 'entity-type')
67007                 .text(function(d) { return d.type; });
67008
67009             label.append('span')
67010                 .attr('class', 'entity-name')
67011                 .text(function(d) { return d.name; });
67012
67013             enter.style('opacity', 0)
67014                 .transition()
67015                 .style('opacity', 1);
67016
67017             items.order();
67018
67019             items.exit()
67020                 .remove();
67021         }
67022
67023
67024         function mouseover(d) {
67025             if (d.id === -1) return;
67026
67027             context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
67028                 .classed('hover', true);
67029         }
67030
67031
67032         function mouseout() {
67033             context.surface().selectAll('.hover')
67034                 .classed('hover', false);
67035         }
67036
67037
67038         function click(d) {
67039             event.preventDefault();
67040             if (d.location) {
67041                 context.map().centerZoom([d.location[1], d.location[0]], 20);
67042             }
67043             else if (d.entity) {
67044                 if (d.entity.type === 'node') {
67045                     context.map().center(d.entity.loc);
67046                 } else if (d.entity.type === 'way') {
67047                     var center = context.projection(context.map().center()),
67048                         edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
67049                     context.map().center(edge.loc);
67050                 }
67051                 context.enter(modeSelect(context, [d.entity.id]));
67052             } else {
67053                 context.zoomToEntity(d.id);
67054             }
67055         }
67056
67057
67058         function geocoderSearch() {
67059             services.geocoder.search(search.property('value'), function (err, resp) {
67060                 geocodeResults = resp || [];
67061                 drawList();
67062             });
67063         }
67064     }
67065
67066
67067     return featureList;
67068 }
67069
67070 function uiPresetIcon() {
67071     var preset, geometry;
67072
67073
67074     function presetIcon(selection$$1) {
67075         selection$$1.each(render);
67076     }
67077
67078
67079     function getIcon(p, geom) {
67080         if (p.icon)
67081             return p.icon;
67082         else if (geom === 'line')
67083             return 'other-line';
67084         else if (geom === 'vertex')
67085             return p.isFallback() ? '' : 'poi-vertex';
67086         else
67087             return 'marker-stroked';
67088     }
67089
67090
67091     function render() {
67092         var selection$$1 = select(this),
67093             p = preset.apply(this, arguments),
67094             geom = geometry.apply(this, arguments),
67095             picon = getIcon(p, geom),
67096             isPoi = picon.match(/^poi-/) !== null,
67097             isMaki = dataFeatureIcons.indexOf(picon) !== -1,
67098             isFramed = (geom === 'area' || geom === 'verex');
67099
67100
67101         function tag_classes(p) {
67102             var s = '';
67103             for (var i in p.tags) {
67104                 s += ' tag-' + i;
67105                 if (p.tags[i] !== '*') {
67106                     s += ' tag-' + i + '-' + p.tags[i];
67107                 }
67108             }
67109             return s;
67110         }
67111
67112
67113         var fill = selection$$1.selectAll('.preset-icon-fill')
67114             .data([0]);
67115
67116         fill = fill.enter()
67117             .append('div')
67118             .merge(fill);
67119
67120         fill
67121             .attr('class', function() {
67122                 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
67123             });
67124
67125
67126         var areaFrame = selection$$1.selectAll('.preset-icon-frame')
67127             .data((geom === 'area') ? [0] : []);
67128
67129         areaFrame.exit()
67130             .remove();
67131
67132         areaFrame = areaFrame.enter()
67133             .append('div')
67134             .attr('class', 'preset-icon-frame')
67135             .call(svgIcon('#preset-icon-frame'));
67136
67137
67138         var icon = selection$$1.selectAll('.preset-icon')
67139             .data([0]);
67140
67141         icon = icon.enter()
67142             .append('div')
67143             .attr('class', 'preset-icon')
67144             .call(svgIcon(''))
67145             .merge(icon);
67146
67147         icon
67148             .attr('class', 'preset-icon preset-icon-' +
67149                 ((isMaki || isPoi) ? (isFramed ? '24' : '28') : (isFramed ? '44' : '60'))
67150             );
67151
67152         icon.selectAll('svg')
67153             .attr('class', function() {
67154                 return 'icon ' + picon + (isMaki || isPoi ? '' : tag_classes(p));
67155             });
67156
67157         icon.selectAll('use')
67158             .attr('href', '#' + picon + (isMaki ? '-15' : ''));
67159     }
67160
67161
67162     presetIcon.preset = function(_) {
67163         if (!arguments.length) return preset;
67164         preset = utilFunctor(_);
67165         return presetIcon;
67166     };
67167
67168
67169     presetIcon.geometry = function(_) {
67170         if (!arguments.length) return geometry;
67171         geometry = utilFunctor(_);
67172         return presetIcon;
67173     };
67174
67175     return presetIcon;
67176 }
67177
67178 function d3combobox() {
67179     var dispatch$$1 = dispatch('accept'),
67180         container = select(document.body),
67181         data = [],
67182         suggestions = [],
67183         minItems = 2,
67184         caseSensitive = false;
67185
67186     var fetcher = function(val, cb) {
67187         cb(data.filter(function(d) {
67188             return d.value
67189                 .toString()
67190                 .toLowerCase()
67191                 .indexOf(val.toLowerCase()) !== -1;
67192         }));
67193     };
67194
67195     var combobox = function(input, attachTo) {
67196         var idx = -1,
67197             wrapper = container
67198                 .selectAll('div.combobox')
67199                 .filter(function(d) { return d === input.node(); }),
67200             shown = !wrapper.empty();
67201
67202         input
67203             .classed('combobox-input', true)
67204             .on('focus.typeahead', focus)
67205             .on('blur.typeahead', blur)
67206             .on('keydown.typeahead', keydown)
67207             .on('keyup.typeahead', keyup)
67208             .on('input.typeahead', change)
67209             .each(function() {
67210                 var parent = this.parentNode,
67211                     sibling = this.nextSibling;
67212
67213                 var caret = select(parent).selectAll('.combobox-caret')
67214                     .filter(function(d) { return d === input.node(); })
67215                     .data([input.node()]);
67216
67217                 caret = caret.enter()
67218                   .insert('div', function() { return sibling; })
67219                     .attr('class', 'combobox-caret')
67220                   .merge(caret);
67221
67222                 caret
67223                     .on('mousedown', function () {
67224                         // prevent the form element from blurring. it blurs
67225                         // on mousedown
67226                         event.stopPropagation();
67227                         event.preventDefault();
67228                         if (!shown) {
67229                             input.node().focus();
67230                             fetch('', render);
67231                         } else {
67232                             hide();
67233                         }
67234                     });
67235             });
67236
67237         function focus() {
67238             fetch(value(), render);
67239         }
67240
67241         function blur() {
67242             window.setTimeout(hide, 150);
67243         }
67244
67245         function show() {
67246             if (!shown) {
67247                 wrapper = container
67248                     .insert('div', ':first-child')
67249                     .datum(input.node())
67250                     .attr('class', 'combobox')
67251                     .style('position', 'absolute')
67252                     .style('display', 'block')
67253                     .style('left', '0px')
67254                     .on('mousedown', function () {
67255                         // prevent moving focus out of the text field
67256                         event.preventDefault();
67257                     });
67258
67259                 select('body')
67260                     .on('scroll.combobox', render, true);
67261
67262                 shown = true;
67263             }
67264         }
67265
67266         function hide() {
67267             if (shown) {
67268                 idx = -1;
67269                 wrapper.remove();
67270
67271                 select('body')
67272                     .on('scroll.combobox', null);
67273
67274                 shown = false;
67275             }
67276         }
67277
67278         function keydown() {
67279            switch (event.keyCode) {
67280                // backspace, delete
67281                case 8:
67282                case 46:
67283                    input.on('input.typeahead', function() {
67284                        idx = -1;
67285                        render();
67286                        var start = input.property('selectionStart');
67287                        input.node().setSelectionRange(start, start);
67288                        input.on('input.typeahead', change);
67289                    });
67290                    break;
67291                // tab
67292                case 9:
67293                    wrapper.selectAll('a.selected').each(function (d) {
67294                        dispatch$$1.call('accept', this, d);
67295                    });
67296                    hide();
67297                    break;
67298                // return
67299                case 13:
67300                    event.preventDefault();
67301                    break;
67302                // up arrow
67303                case 38:
67304                    nav(-1);
67305                    event.preventDefault();
67306                    break;
67307                // down arrow
67308                case 40:
67309                    nav(+1);
67310                    event.preventDefault();
67311                    break;
67312            }
67313            event.stopPropagation();
67314         }
67315
67316         function keyup() {
67317             switch (event.keyCode) {
67318                 // escape
67319                 case 27:
67320                     hide();
67321                     break;
67322                 // return
67323                 case 13:
67324                     wrapper.selectAll('a.selected').each(function (d) {
67325                        dispatch$$1.call('accept', this, d);
67326                     });
67327                     hide();
67328                     break;
67329             }
67330         }
67331
67332         function change() {
67333             fetch(value(), function() {
67334                 if (input.property('selectionEnd') === input.property('value').length) {
67335                     autocomplete();
67336                 }
67337                 render();
67338             });
67339         }
67340
67341         function nav(dir) {
67342             if (!suggestions.length) return;
67343             idx = Math.max(Math.min(idx + dir, suggestions.length - 1), 0);
67344             input.property('value', suggestions[idx].value);
67345             render();
67346             ensureVisible();
67347         }
67348
67349         function value() {
67350             var value = input.property('value'),
67351                 start = input.property('selectionStart'),
67352                 end = input.property('selectionEnd');
67353
67354             if (start && end) {
67355                 value = value.substring(0, start);
67356             }
67357
67358             return value;
67359         }
67360
67361         function fetch(v, cb) {
67362             fetcher.call(input, v, function(_) {
67363                 suggestions = _;
67364                 cb();
67365             });
67366         }
67367
67368         function autocomplete() {
67369             var v = caseSensitive ? value() : value().toLowerCase();
67370             idx = -1;
67371             if (!v) return;
67372
67373             for (var i = 0; i < suggestions.length; i++) {
67374                 var suggestion = suggestions[i].value,
67375                     compare = caseSensitive ? suggestion : suggestion.toLowerCase();
67376
67377                 if (compare.indexOf(v) === 0) {
67378                     idx = i;
67379                     input.property('value', suggestion);
67380                     input.node().setSelectionRange(v.length, suggestion.length);
67381                     return;
67382                 }
67383             }
67384         }
67385
67386         function render() {
67387             if (suggestions.length >= minItems && document.activeElement === input.node()) {
67388                 show();
67389             } else {
67390                 hide();
67391                 return;
67392             }
67393
67394             var options = wrapper
67395                 .selectAll('a.combobox-option')
67396                 .data(suggestions, function(d) { return d.value; });
67397
67398             options.exit()
67399                 .remove();
67400
67401             options.enter()
67402                 .append('a')
67403                 .attr('class', 'combobox-option')
67404                 .text(function(d) { return d.value; })
67405                 .merge(options)
67406                 .attr('title', function(d) { return d.title; })
67407                 .classed('selected', function(d, i) { return i === idx; })
67408                 .on('mouseover', select$$1)
67409                 .on('click', accept)
67410                 .order();
67411
67412
67413             var node = attachTo ? attachTo.node() : input.node(),
67414                 rect = node.getBoundingClientRect();
67415
67416             wrapper
67417                 .style('left', rect.left + 'px')
67418                 .style('width', rect.width + 'px')
67419                 .style('top', rect.height + rect.top + 'px');
67420         }
67421
67422         function select$$1(d, i) {
67423             idx = i;
67424             render();
67425         }
67426
67427         function ensureVisible() {
67428             var node = wrapper.selectAll('a.selected').node();
67429             if (node) node.scrollIntoView();
67430         }
67431
67432         function accept(d) {
67433             if (!shown) return;
67434             input.property('value', d.value);
67435             utilTriggerEvent(input, 'change');
67436             dispatch$$1.call('accept', this, d);
67437             hide();
67438         }
67439     };
67440
67441     combobox.fetcher = function(_) {
67442         if (!arguments.length) return fetcher;
67443         fetcher = _;
67444         return combobox;
67445     };
67446
67447     combobox.data = function(_) {
67448         if (!arguments.length) return data;
67449         data = _;
67450         return combobox;
67451     };
67452
67453     combobox.minItems = function(_) {
67454         if (!arguments.length) return minItems;
67455         minItems = _;
67456         return combobox;
67457     };
67458
67459     combobox.caseSensitive = function(_) {
67460         if (!arguments.length) return caseSensitive;
67461         caseSensitive = _;
67462         return combobox;
67463     };
67464
67465     combobox.container = function(_) {
67466         if (!arguments.length) return container;
67467         container = _;
67468         return combobox;
67469     };
67470
67471     return utilRebind(combobox, dispatch$$1, 'on');
67472 }
67473
67474
67475 d3combobox.off = function(input) {
67476     input
67477         .on('focus.typeahead', null)
67478         .on('blur.typeahead', null)
67479         .on('keydown.typeahead', null)
67480         .on('keyup.typeahead', null)
67481         .on('input.typeahead', null)
67482         .each(function() {
67483             select(this.parentNode).selectAll('.combobox-caret')
67484                 .filter(function(d) { return d === input.node(); })
67485                 .on('mousedown', null);
67486         });
67487
67488     select('body')
67489         .on('scroll.combobox', null);
67490 };
67491
67492 function uiDisclosure() {
67493     var dispatch$$1 = dispatch('toggled'),
67494         title,
67495         expanded = false,
67496         content = function () {};
67497
67498
67499     var disclosure = function(selection$$1) {
67500         var hideToggle = selection$$1.selectAll('.hide-toggle')
67501             .data([0]);
67502
67503         hideToggle = hideToggle.enter()
67504             .append('a')
67505             .attr('href', '#')
67506             .attr('class', 'hide-toggle')
67507             .merge(hideToggle);
67508
67509         hideToggle
67510             .text(title)
67511             .on('click', toggle)
67512             .classed('expanded', expanded);
67513
67514
67515         var wrap = selection$$1.selectAll('div')
67516             .data([0]);
67517
67518         wrap = wrap.enter()
67519             .append('div')
67520             .merge(wrap);
67521
67522         wrap
67523             .classed('hide', !expanded)
67524             .call(content);
67525
67526
67527         function toggle() {
67528             expanded = !expanded;
67529             hideToggle.classed('expanded', expanded);
67530             wrap.call(uiToggle(expanded));
67531             dispatch$$1.call('toggled', this, expanded);
67532         }
67533     };
67534
67535
67536     disclosure.title = function(_) {
67537         if (!arguments.length) return title;
67538         title = _;
67539         return disclosure;
67540     };
67541
67542
67543     disclosure.expanded = function(_) {
67544         if (!arguments.length) return expanded;
67545         expanded = _;
67546         return disclosure;
67547     };
67548
67549
67550     disclosure.content = function(_) {
67551         if (!arguments.length) return content;
67552         content = _;
67553         return disclosure;
67554     };
67555
67556
67557     return utilRebind(disclosure, dispatch$$1, 'on');
67558 }
67559
67560 function uiRawMemberEditor(context) {
67561     var id,
67562         taginfo = services.taginfo;
67563
67564
67565     function selectMember(d) {
67566         event.preventDefault();
67567         context.enter(modeSelect(context, [d.id]));
67568     }
67569
67570
67571     function changeRole(d) {
67572         var role = select(this).property('value');
67573         var member = { id: d.id, type: d.type, role: role };
67574         context.perform(
67575             actionChangeMember(d.relation.id, member, d.index),
67576             t('operations.change_role.annotation')
67577         );
67578     }
67579
67580
67581     function deleteMember(d) {
67582         context.perform(
67583             actionDeleteMember(d.relation.id, d.index),
67584             t('operations.delete_member.annotation')
67585         );
67586
67587         if (!context.hasEntity(d.relation.id)) {
67588             context.enter(modeBrowse(context));
67589         }
67590     }
67591
67592
67593     function rawMemberEditor(selection$$1) {
67594         var entity = context.entity(id),
67595             memberships = [];
67596
67597         entity.members.slice(0, 1000).forEach(function(member, index) {
67598             memberships.push({
67599                 index: index,
67600                 id: member.id,
67601                 type: member.type,
67602                 role: member.role,
67603                 relation: entity,
67604                 member: context.hasEntity(member.id)
67605             });
67606         });
67607
67608         var gt = entity.members.length > 1000 ? '>' : '';
67609         selection$$1.call(uiDisclosure()
67610             .title(t('inspector.all_members') + ' (' + gt + memberships.length + ')')
67611             .expanded(true)
67612             .on('toggled', toggled)
67613             .content(content)
67614         );
67615
67616
67617         function toggled(expanded) {
67618             if (expanded) {
67619                 selection$$1.node().parentNode.scrollTop += 200;
67620             }
67621         }
67622
67623
67624         function content(wrap) {
67625             var list = wrap.selectAll('.member-list')
67626                 .data([0]);
67627
67628             list = list.enter()
67629                 .append('ul')
67630                 .attr('class', 'member-list')
67631                 .merge(list);
67632
67633
67634             var items = list.selectAll('li')
67635                 .data(memberships, function(d) {
67636                     return osmEntity$$1.key(d.relation) + ',' + d.index + ',' +
67637                         (d.member ? osmEntity$$1.key(d.member) : 'incomplete');
67638                 });
67639
67640             items.exit()
67641                 .each(unbind)
67642                 .remove();
67643
67644             var enter = items.enter()
67645                 .append('li')
67646                 .attr('class', 'member-row form-field')
67647                 .classed('member-incomplete', function(d) { return !d.member; });
67648
67649             enter
67650                 .each(function(d) {
67651                     if (d.member) {
67652                         var label = select(this).append('label')
67653                             .attr('class', 'form-label')
67654                             .append('a')
67655                             .attr('href', '#')
67656                             .on('click', selectMember);
67657
67658                         label.append('span')
67659                             .attr('class', 'member-entity-type')
67660                             .text(function(d) {
67661                                 var matched = context.presets().match(d.member, context.graph());
67662                                 return (matched && matched.name()) || utilDisplayType(d.member.id);
67663                             });
67664
67665                         label.append('span')
67666                             .attr('class', 'member-entity-name')
67667                             .text(function(d) { return utilDisplayName(d.member); });
67668
67669                     } else {
67670                         select(this).append('label')
67671                             .attr('class', 'form-label')
67672                             .text(t('inspector.incomplete', { id: d.id }));
67673                     }
67674                 });
67675
67676             enter
67677                 .append('input')
67678                 .attr('class', 'member-role')
67679                 .property('type', 'text')
67680                 .attr('maxlength', 255)
67681                 .attr('placeholder', t('inspector.role'))
67682                 .call(utilNoAuto)
67683                 .property('value', function(d) { return d.role; })
67684                 .on('change', changeRole);
67685
67686             enter
67687                 .append('button')
67688                 .attr('tabindex', -1)
67689                 .attr('class', 'remove button-input-action member-delete minor')
67690                 .on('click', deleteMember)
67691                 .call(svgIcon('#operation-delete'));
67692
67693             if (taginfo) {
67694                 enter.each(bindTypeahead);
67695             }
67696
67697
67698             function bindTypeahead(d) {
67699                 var row = select(this),
67700                     role = row.selectAll('input.member-role');
67701
67702                 function sort(value, data) {
67703                     var sameletter = [],
67704                         other = [];
67705                     for (var i = 0; i < data.length; i++) {
67706                         if (data[i].value.substring(0, value.length) === value) {
67707                             sameletter.push(data[i]);
67708                         } else {
67709                             other.push(data[i]);
67710                         }
67711                     }
67712                     return sameletter.concat(other);
67713                 }
67714
67715                 role.call(d3combobox()
67716                     .container(context.container())
67717                     .fetcher(function(role, callback) {
67718                         var rtype = entity.tags.type;
67719                         taginfo.roles({
67720                             debounce: true,
67721                             rtype: rtype || '',
67722                             geometry: context.geometry(d.member.id),
67723                             query: role
67724                         }, function(err, data) {
67725                             if (!err) callback(sort(role, data));
67726                         });
67727                     }));
67728             }
67729
67730
67731             function unbind() {
67732                 var row = select(this);
67733
67734                 row.selectAll('input.member-role')
67735                     .call(d3combobox.off);
67736             }
67737         }
67738     }
67739
67740
67741     rawMemberEditor.entityID = function(_) {
67742         if (!arguments.length) return id;
67743         id = _;
67744         return rawMemberEditor;
67745     };
67746
67747
67748     return rawMemberEditor;
67749 }
67750
67751 function uiRawMembershipEditor(context) {
67752     var taginfo = services.taginfo,
67753         id, showBlank;
67754
67755
67756     function selectRelation(d) {
67757         event.preventDefault();
67758         context.enter(modeSelect(context, [d.relation.id]));
67759     }
67760
67761
67762     function changeRole(d) {
67763         var role = select(this).property('value');
67764         context.perform(
67765             actionChangeMember(d.relation.id, lodash.extend({}, d.member, { role: role }), d.index),
67766             t('operations.change_role.annotation')
67767         );
67768     }
67769
67770
67771     function addMembership(d, role) {
67772         showBlank = false;
67773
67774         if (d.relation) {
67775             context.perform(
67776                 actionAddMember(d.relation.id, { id: id, type: context.entity(id).type, role: role }),
67777                 t('operations.add_member.annotation')
67778             );
67779
67780         } else {
67781             var relation = osmRelation();
67782             context.perform(
67783                 actionAddEntity(relation),
67784                 actionAddMember(relation.id, { id: id, type: context.entity(id).type, role: role }),
67785                 t('operations.add.annotation.relation')
67786             );
67787
67788             context.enter(modeSelect(context, [relation.id]));
67789         }
67790     }
67791
67792
67793     function deleteMembership(d) {
67794         context.perform(
67795             actionDeleteMember(d.relation.id, d.index),
67796             t('operations.delete_member.annotation')
67797         );
67798     }
67799
67800
67801     function relations(q) {
67802         var newRelation = {
67803                 relation: null,
67804                 value: t('inspector.new_relation')
67805             },
67806             result = [],
67807             graph = context.graph();
67808
67809         context.intersects(context.extent()).forEach(function(entity) {
67810             if (entity.type !== 'relation' || entity.id === id)
67811                 return;
67812
67813             var matched = context.presets().match(entity, graph),
67814                 presetName = (matched && matched.name()) || t('inspector.relation'),
67815                 entityName = utilDisplayName(entity) || '';
67816
67817             var value = presetName + ' ' + entityName;
67818             if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
67819                 return;
67820
67821             result.push({
67822                 relation: entity,
67823                 value: value
67824             });
67825         });
67826
67827         result.sort(function(a, b) {
67828             return osmRelation.creationOrder(a.relation, b.relation);
67829         });
67830
67831         // Dedupe identical names by appending relation id - see #2891
67832         var dupeGroups = lodash(result)
67833             .groupBy('value')
67834             .filter(function(v) { return v.length > 1; })
67835             .value();
67836
67837         dupeGroups.forEach(function(group) {
67838             group.forEach(function(obj) {
67839                 obj.value += ' ' + obj.relation.id;
67840             });
67841         });
67842
67843         result.unshift(newRelation);
67844         return result;
67845     }
67846
67847
67848     function rawMembershipEditor(selection$$1) {
67849         var entity = context.entity(id),
67850             parents = context.graph().parentRelations(entity),
67851             memberships = [];
67852
67853         parents.slice(0, 1000).forEach(function(relation) {
67854             relation.members.forEach(function(member, index) {
67855                 if (member.id === entity.id) {
67856                     memberships.push({ relation: relation, member: member, index: index });
67857                 }
67858             });
67859         });
67860
67861         var gt = parents.length > 1000 ? '>' : '';
67862         selection$$1.call(uiDisclosure()
67863             .title(t('inspector.all_relations') + ' (' + gt + memberships.length + ')')
67864             .expanded(true)
67865             .on('toggled', toggled)
67866             .content(content)
67867         );
67868
67869
67870         function toggled(expanded) {
67871             if (expanded) {
67872                 selection$$1.node().parentNode.scrollTop += 200;
67873             }
67874         }
67875
67876
67877         function content(wrap) {
67878             var list = wrap.selectAll('.member-list')
67879                 .data([0]);
67880
67881             list = list.enter()
67882                 .append('ul')
67883                 .attr('class', 'member-list')
67884                 .merge(list);
67885
67886
67887             var items = list.selectAll('li.member-row-normal')
67888                 .data(memberships, function(d) {
67889                     return osmEntity$$1.key(d.relation) + ',' + d.index;
67890                 });
67891
67892             items.exit()
67893                 .each(unbind)
67894                 .remove();
67895
67896             var enter = items.enter()
67897                 .append('li')
67898                 .attr('class', 'member-row member-row-normal form-field');
67899
67900             var label = enter
67901                 .append('label')
67902                 .attr('class', 'form-label')
67903                 .append('a')
67904                 .attr('href', '#')
67905                 .on('click', selectRelation);
67906
67907             label
67908                 .append('span')
67909                 .attr('class', 'member-entity-type')
67910                 .text(function(d) {
67911                     var matched = context.presets().match(d.relation, context.graph());
67912                     return (matched && matched.name()) || t('inspector.relation');
67913                 });
67914
67915             label
67916                 .append('span')
67917                 .attr('class', 'member-entity-name')
67918                 .text(function(d) { return utilDisplayName(d.relation); });
67919
67920             enter
67921                 .append('input')
67922                 .attr('class', 'member-role')
67923                 .property('type', 'text')
67924                 .attr('maxlength', 255)
67925                 .attr('placeholder', t('inspector.role'))
67926                 .call(utilNoAuto)
67927                 .property('value', function(d) { return d.member.role; })
67928                 .on('change', changeRole);
67929
67930             enter
67931                 .append('button')
67932                 .attr('tabindex', -1)
67933                 .attr('class', 'remove button-input-action member-delete minor')
67934                 .on('click', deleteMembership)
67935                 .call(svgIcon('#operation-delete'));
67936
67937             if (taginfo) {
67938                 enter.each(bindTypeahead);
67939             }
67940
67941
67942             var newrow = list.selectAll('.member-row-new')
67943                 .data(showBlank ? [0] : []);
67944
67945             newrow.exit()
67946                 .remove();
67947
67948             enter = newrow.enter()
67949                 .append('li')
67950                 .attr('class', 'member-row member-row-new form-field');
67951
67952             enter
67953                 .append('input')
67954                 .attr('type', 'text')
67955                 .attr('class', 'member-entity-input')
67956                 .call(utilNoAuto);
67957
67958             enter
67959                 .append('input')
67960                 .attr('class', 'member-role')
67961                 .property('type', 'text')
67962                 .attr('maxlength', 255)
67963                 .attr('placeholder', t('inspector.role'))
67964                 .call(utilNoAuto)
67965                 .on('change', changeRole);
67966
67967             enter
67968                 .append('button')
67969                 .attr('tabindex', -1)
67970                 .attr('class', 'remove button-input-action member-delete minor')
67971                 .on('click', deleteMembership)
67972                 .call(svgIcon('#operation-delete'));
67973
67974             newrow = newrow
67975                 .merge(enter);
67976
67977             newrow.selectAll('.member-entity-input')
67978                 .call(d3combobox()
67979                     .container(context.container())
67980                     .minItems(1)
67981                     .fetcher(function(value, callback) { callback(relations(value)); })
67982                     .on('accept', onAccept)
67983                 );
67984
67985
67986             var addrel = wrap.selectAll('.add-relation')
67987                 .data([0]);
67988
67989             addrel = addrel.enter()
67990                 .append('button')
67991                 .attr('class', 'add-relation')
67992                 .merge(addrel);
67993
67994             addrel
67995                 .call(svgIcon('#icon-plus', 'light'))
67996                 .on('click', function() {
67997                     showBlank = true;
67998                     content(wrap);
67999                     list.selectAll('.member-entity-input').node().focus();
68000                 });
68001
68002
68003             function onAccept(d) {
68004                 var role = list.selectAll('.member-row-new .member-role').property('value');
68005                 addMembership(d, role);
68006             }
68007
68008
68009             function bindTypeahead(d) {
68010                 var row = select(this),
68011                     role = row.selectAll('input.member-role');
68012
68013                 function sort(value, data) {
68014                     var sameletter = [],
68015                         other = [];
68016                     for (var i = 0; i < data.length; i++) {
68017                         if (data[i].value.substring(0, value.length) === value) {
68018                             sameletter.push(data[i]);
68019                         } else {
68020                             other.push(data[i]);
68021                         }
68022                     }
68023                     return sameletter.concat(other);
68024                 }
68025
68026                 role.call(d3combobox()
68027                     .container(context.container())
68028                     .fetcher(function(role, callback) {
68029                         var rtype = d.relation.tags.type;
68030                         taginfo.roles({
68031                             debounce: true,
68032                             rtype: rtype || '',
68033                             geometry: context.geometry(id),
68034                             query: role
68035                         }, function(err, data) {
68036                             if (!err) callback(sort(role, data));
68037                         });
68038                     }));
68039             }
68040
68041
68042             function unbind() {
68043                 var row = select(this);
68044
68045                 row.selectAll('input.member-role')
68046                     .call(d3combobox.off);
68047             }
68048         }
68049     }
68050
68051
68052     rawMembershipEditor.entityID = function(_) {
68053         if (!arguments.length) return id;
68054         id = _;
68055         return rawMembershipEditor;
68056     };
68057
68058
68059     return rawMembershipEditor;
68060 }
68061
68062 function uiTagReference(tag) {
68063     var taginfo = services.taginfo,
68064         tagReference = {},
68065         button = select(null),
68066         body = select(null),
68067         loaded,
68068         showing;
68069
68070
68071     function findLocal(data) {
68072         var locale = utilDetect().locale.toLowerCase(),
68073             localized;
68074
68075         if (locale !== 'pt-br') {  // see #3776, prefer 'pt' over 'pt-br'
68076             localized = lodash.find(data, function(d) {
68077                 return d.lang.toLowerCase() === locale;
68078             });
68079             if (localized) return localized;
68080         }
68081
68082         // try the non-regional version of a language, like
68083         // 'en' if the language is 'en-US'
68084         if (locale.indexOf('-') !== -1) {
68085             var first = locale.split('-')[0];
68086             localized = lodash.find(data, function(d) {
68087                 return d.lang.toLowerCase() === first;
68088             });
68089             if (localized) return localized;
68090         }
68091
68092         // finally fall back to english
68093         return lodash.find(data, function(d) {
68094             return d.lang.toLowerCase() === 'en';
68095         });
68096     }
68097
68098
68099     function load(param) {
68100         if (!taginfo) return;
68101
68102         button
68103             .classed('tag-reference-loading', true);
68104
68105         taginfo.docs(param, function show(err, data) {
68106             var docs;
68107             if (!err && data) {
68108                 docs = findLocal(data);
68109             }
68110
68111             body.html('');
68112
68113             if (!docs || !docs.title) {
68114                 if (param.hasOwnProperty('value')) {
68115                     load(lodash.omit(param, 'value'));   // retry with key only
68116                 } else {
68117                     body
68118                         .append('p')
68119                         .attr('class', 'tag-reference-description')
68120                         .text(t('inspector.no_documentation_key'));
68121                     done();
68122                 }
68123                 return;
68124             }
68125
68126             if (docs.image && docs.image.thumb_url_prefix) {
68127                 body
68128                     .append('img')
68129                     .attr('class', 'tag-reference-wiki-image')
68130                     .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
68131                     .on('load', function() { done(); })
68132                     .on('error', function() { select(this).remove(); done(); });
68133             } else {
68134                 done();
68135             }
68136
68137             body
68138                 .append('p')
68139                 .attr('class', 'tag-reference-description')
68140                 .text(docs.description || t('inspector.documentation_redirect'));
68141
68142             body
68143                 .append('a')
68144                 .attr('class', 'tag-reference-link')
68145                 .attr('target', '_blank')
68146                 .attr('tabindex', -1)
68147                 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
68148                 .call(svgIcon('#icon-out-link', 'inline'))
68149                 .append('span')
68150                 .text(t('inspector.reference'));
68151
68152             // Add link to info about "good changeset comments" - #2923
68153             if (param.key === 'comment') {
68154                 body
68155                     .append('a')
68156                     .attr('class', 'tag-reference-comment-link')
68157                     .attr('target', '_blank')
68158                     .attr('tabindex', -1)
68159                     .call(svgIcon('#icon-out-link', 'inline'))
68160                     .attr('href', t('commit.about_changeset_comments_link'))
68161                     .append('span')
68162                     .text(t('commit.about_changeset_comments'));
68163             }
68164         });
68165     }
68166
68167
68168     function done() {
68169         loaded = true;
68170
68171         button
68172             .classed('tag-reference-loading', false);
68173
68174         body
68175             .classed('expanded', true)
68176             .transition()
68177             .duration(200)
68178             .style('max-height', '200px')
68179             .style('opacity', '1');
68180
68181         showing = true;
68182     }
68183
68184
68185     function hide() {
68186         body
68187             .transition()
68188             .duration(200)
68189             .style('max-height', '0px')
68190             .style('opacity', '0')
68191             .on('end', function () {
68192                 body.classed('expanded', false);
68193             });
68194
68195         showing = false;
68196     }
68197
68198
68199     tagReference.button = function(selection$$1) {
68200         button = selection$$1.selectAll('.tag-reference-button')
68201             .data([0]);
68202
68203         button = button.enter()
68204             .append('button')
68205             .attr('class', 'tag-reference-button')
68206             .attr('tabindex', -1)
68207             .call(svgIcon('#icon-inspect'))
68208             .merge(button);
68209
68210         button
68211             .on('click', function () {
68212                 event.stopPropagation();
68213                 event.preventDefault();
68214                 if (showing) {
68215                     hide();
68216                 } else if (loaded) {
68217                     done();
68218                 } else {
68219                     load(tag);
68220                 }
68221             });
68222     };
68223
68224
68225     tagReference.body = function(selection$$1) {
68226         body = selection$$1.selectAll('.tag-reference-body')
68227             .data([0]);
68228
68229         body = body.enter()
68230             .append('div')
68231             .attr('class', 'tag-reference-body cf')
68232             .style('max-height', '0')
68233             .style('opacity', '0')
68234             .merge(body);
68235
68236         if (showing === false) {
68237             hide();
68238         }
68239     };
68240
68241
68242     tagReference.showing = function(_) {
68243         if (!arguments.length) return showing;
68244         showing = _;
68245         return tagReference;
68246     };
68247
68248
68249     return tagReference;
68250 }
68251
68252 function uiRawTagEditor(context) {
68253     var taginfo = services.taginfo,
68254         dispatch$$1 = dispatch('change'),
68255         expandedPreference = (context.storage('raw_tag_editor.expanded') === 'true'),
68256         expandedCurrent = expandedPreference,
68257         updatePreference = true,
68258         readOnlyTags = [],
68259         showBlank = false,
68260         newRow,
68261         state,
68262         preset,
68263         tags,
68264         id;
68265
68266
68267     function rawTagEditor(selection$$1) {
68268         var count = Object.keys(tags).filter(function(d) { return d; }).length;
68269
68270         selection$$1.call(uiDisclosure()
68271             .title(t('inspector.all_tags') + ' (' + count + ')')
68272             .expanded(expandedCurrent)
68273             .on('toggled', toggled)
68274             .content(content)
68275         );
68276
68277         function toggled(expanded) {
68278             expandedCurrent = expanded;
68279             if (updatePreference) {
68280                 expandedPreference = expanded;
68281                 context.storage('raw_tag_editor.expanded', expanded);
68282             }
68283             if (expanded) {
68284                 selection$$1.node().parentNode.scrollTop += 200;
68285             }
68286         }
68287     }
68288
68289
68290     function content(wrap) {
68291         var entries$$1 = entries(tags);
68292
68293         if (!entries$$1.length || showBlank) {
68294             showBlank = false;
68295             entries$$1.push({key: '', value: ''});
68296             newRow = '';
68297         }
68298
68299         var list = wrap.selectAll('.tag-list')
68300             .data([0]);
68301
68302         list = list.enter()
68303             .append('ul')
68304             .attr('class', 'tag-list')
68305             .merge(list);
68306
68307         var newTag = wrap.selectAll('.add-tag')
68308             .data([0]);
68309
68310         newTag.enter()
68311             .append('button')
68312             .attr('class', 'add-tag')
68313             .on('click', addTag)
68314             .call(svgIcon('#icon-plus', 'light'));
68315
68316
68317         var items = list.selectAll('.tag-row')
68318             .data(entries$$1, function(d) { return d.key; });
68319
68320         items.exit()
68321             .each(unbind)
68322             .remove();
68323
68324         // Enter
68325
68326         var enter = items.enter()
68327             .append('li')
68328             .attr('class', 'tag-row cf')
68329             .classed('readonly', isReadOnly);
68330
68331         enter
68332             .append('div')
68333             .attr('class', 'key-wrap')
68334             .append('input')
68335             .property('type', 'text')
68336             .attr('class', 'key')
68337             .attr('maxlength', 255)
68338             .call(utilNoAuto)
68339             .on('blur', keyChange)
68340             .on('change', keyChange);
68341
68342         enter
68343             .append('div')
68344             .attr('class', 'input-wrap-position')
68345             .append('input')
68346             .property('type', 'text')
68347             .attr('class', 'value')
68348             .attr('maxlength', 255)
68349             .call(utilNoAuto)
68350             .on('blur', valueChange)
68351             .on('change', valueChange)
68352             .on('keydown.push-more', pushMore);
68353
68354         enter
68355             .append('button')
68356             .attr('tabindex', -1)
68357             .attr('class', 'remove minor')
68358             .call(svgIcon('#operation-delete'));
68359
68360
68361         // Update
68362
68363         items = items
68364             .merge(enter)
68365             .sort(function(a, b) {
68366                 return (a.key === newRow && b.key !== newRow) ? 1
68367                     : (a.key !== newRow && b.key === newRow) ? -1
68368                     : ascending(a.key, b.key);
68369             });
68370
68371         items
68372             .each(function(tag) {
68373                 var row = select(this),
68374                     key = row.select('input.key'),      // propagate bound data to child
68375                     value = row.select('input.value');  // propagate bound data to child
68376
68377                 if (id && taginfo) {
68378                     bindTypeahead(key, value);
68379                 }
68380
68381                 var isRelation = (id && context.entity(id).type === 'relation'),
68382                     reference;
68383
68384                 if (isRelation && tag.key === 'type') {
68385                     reference = uiTagReference({ rtype: tag.value }, context);
68386                 } else {
68387                     reference = uiTagReference({ key: tag.key, value: tag.value }, context);
68388                 }
68389
68390                 if (state === 'hover') {
68391                     reference.showing(false);
68392                 }
68393
68394                 row
68395                     .call(reference.button)
68396                     .call(reference.body);
68397             });
68398
68399         items.selectAll('input.key')
68400             .attr('title', function(d) { return d.key; })
68401             .call(utilGetSetValue, function(d) { return d.key; })
68402             .property('disabled', isReadOnly);
68403
68404         items.selectAll('input.value')
68405             .attr('title', function(d) { return d.value; })
68406             .call(utilGetSetValue, function(d) { return d.value; })
68407             .property('disabled', isReadOnly);
68408
68409         items.selectAll('button.remove')
68410             .on('click', removeTag);
68411
68412
68413
68414         function isReadOnly(d) {
68415             for (var i = 0; i < readOnlyTags.length; i++) {
68416                 if (d.key.match(readOnlyTags[i]) !== null) {
68417                     return true;
68418                 }
68419             }
68420             return false;
68421         }
68422
68423
68424         function pushMore() {
68425             if (event.keyCode === 9 && !event.shiftKey &&
68426                 list.selectAll('li:last-child input.value').node() === this) {
68427                 addTag();
68428             }
68429         }
68430
68431
68432         function bindTypeahead(key, value) {
68433             if (isReadOnly({ key: key })) return;
68434             var geometry = context.geometry(id);
68435
68436             key.call(d3combobox()
68437                 .container(context.container())
68438                 .fetcher(function(value, callback) {
68439                     taginfo.keys({
68440                         debounce: true,
68441                         geometry: geometry,
68442                         query: value
68443                     }, function(err, data) {
68444                         if (!err) callback(sort(value, data));
68445                     });
68446                 }));
68447
68448             value.call(d3combobox()
68449                 .container(context.container())
68450                 .fetcher(function(value, callback) {
68451                     taginfo.values({
68452                         debounce: true,
68453                         key: utilGetSetValue(key),
68454                         geometry: geometry,
68455                         query: value
68456                     }, function(err, data) {
68457                         if (!err) callback(sort(value, data));
68458                     });
68459                 }));
68460
68461
68462             function sort(value, data) {
68463                 var sameletter = [],
68464                     other = [];
68465                 for (var i = 0; i < data.length; i++) {
68466                     if (data[i].value.substring(0, value.length) === value) {
68467                         sameletter.push(data[i]);
68468                     } else {
68469                         other.push(data[i]);
68470                     }
68471                 }
68472                 return sameletter.concat(other);
68473             }
68474         }
68475
68476
68477         function unbind() {
68478             var row = select(this);
68479
68480             row.selectAll('input.key')
68481                 .call(d3combobox.off);
68482
68483             row.selectAll('input.value')
68484                 .call(d3combobox.off);
68485         }
68486
68487
68488         function keyChange(d) {
68489             var kOld = d.key,
68490                 kNew = this.value.trim(),
68491                 tag = {};
68492
68493
68494             if (isReadOnly({ key: kNew })) {
68495                 this.value = kOld;
68496                 return;
68497             }
68498
68499             if (kNew && kNew !== kOld) {
68500                 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
68501                     base = match[1],
68502                     suffix = +(match[2] || 1);
68503                 while (tags[kNew]) {  // rename key if already in use
68504                     kNew = base + '_' + suffix++;
68505                 }
68506             }
68507             tag[kOld] = undefined;
68508             tag[kNew] = d.value;
68509
68510             d.key = kNew; // Maintain DOM identity through the subsequent update.
68511
68512             if (newRow === kOld) {  // see if this row is still a new row
68513                 newRow = ((d.value === '' || kNew === '') ? kNew : undefined);
68514             }
68515
68516             this.value = kNew;
68517             dispatch$$1.call('change', this, tag);
68518         }
68519
68520
68521         function valueChange(d) {
68522             if (isReadOnly(d)) return;
68523             var tag = {};
68524             tag[d.key] = this.value;
68525
68526             if (newRow === d.key && d.key !== '' && d.value !== '') {   // not a new row anymore
68527                 newRow = undefined;
68528             }
68529
68530             dispatch$$1.call('change', this, tag);
68531         }
68532
68533
68534         function removeTag(d) {
68535             if (isReadOnly(d)) return;
68536             var tag = {};
68537             tag[d.key] = undefined;
68538             dispatch$$1.call('change', this, tag);
68539             select(this.parentNode).remove();
68540         }
68541
68542
68543         function addTag() {
68544             // Wrapped in a setTimeout in case it's being called from a blur
68545             // handler. Without the setTimeout, the call to `content` would
68546             // wipe out the pending value change.
68547             setTimeout(function() {
68548                 showBlank = true;
68549                 content(wrap);
68550                 list.selectAll('li:last-child input.key').node().focus();
68551             }, 0);
68552         }
68553     }
68554
68555
68556     rawTagEditor.state = function(_) {
68557         if (!arguments.length) return state;
68558         state = _;
68559         return rawTagEditor;
68560     };
68561
68562
68563     rawTagEditor.preset = function(_) {
68564         if (!arguments.length) return preset;
68565         preset = _;
68566         if (preset.isFallback()) {
68567             expandedCurrent = true;
68568             updatePreference = false;
68569         } else {
68570             expandedCurrent = expandedPreference;
68571             updatePreference = true;
68572         }
68573         return rawTagEditor;
68574     };
68575
68576
68577     rawTagEditor.tags = function(_) {
68578         if (!arguments.length) return tags;
68579         tags = _;
68580         return rawTagEditor;
68581     };
68582
68583
68584     rawTagEditor.entityID = function(_) {
68585         if (!arguments.length) return id;
68586         id = _;
68587         return rawTagEditor;
68588     };
68589
68590
68591     rawTagEditor.expanded = function(_) {
68592         if (!arguments.length) return expandedCurrent;
68593         expandedCurrent = _;
68594         updatePreference = false;
68595         return rawTagEditor;
68596     };
68597
68598
68599     rawTagEditor.readOnlyTags = function(_) {
68600         if (!arguments.length) return readOnlyTags;
68601         readOnlyTags = _;
68602         return rawTagEditor;
68603     };
68604
68605
68606     return utilRebind(rawTagEditor, dispatch$$1, 'on');
68607 }
68608
68609 function uiFieldCheck(field, context) {
68610     var dispatch$$1 = dispatch('change'),
68611         options = field.strings && field.strings.options,
68612         values$$1 = [],
68613         texts = [],
68614         input = select(null),
68615         text$$1 = select(null),
68616         label = select(null),
68617         reverser = select(null),
68618         impliedYes,
68619         entityId,
68620         value;
68621
68622
68623     if (options) {
68624         for (var k in options) {
68625             values$$1.push(k === 'undefined' ? undefined : k);
68626             texts.push(field.t('options.' + k, { 'default': options[k] }));
68627         }
68628     } else {
68629         values$$1 = [undefined, 'yes'];
68630         texts = [t('inspector.unknown'), t('inspector.check.yes')];
68631         if (field.type !== 'defaultCheck') {
68632             values$$1.push('no');
68633             texts.push(t('inspector.check.no'));
68634         }
68635     }
68636
68637
68638     // Checks tags to see whether an undefined value is "Assumed to be Yes"
68639     function checkImpliedYes() {
68640         impliedYes = (field.id === 'oneway_yes');
68641
68642         // hack: pretend `oneway` field is a `oneway_yes` field
68643         // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
68644         if (field.id === 'oneway') {
68645             var entity = context.entity(entityId);
68646             for (var key in entity.tags) {
68647                 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
68648                     impliedYes = true;
68649                     texts[0] = t('presets.fields.oneway_yes.options.undefined');
68650                     break;
68651                 }
68652             }
68653         }
68654     }
68655
68656
68657     function reverserHidden() {
68658         if (!select('div.inspector-hover').empty()) return true;
68659         return !(value === 'yes' || (impliedYes && !value));
68660     }
68661
68662
68663     function reverserSetText(selection$$1) {
68664         var entity = context.hasEntity(entityId);
68665         if (reverserHidden() || !entity) return selection$$1;
68666
68667         var first = entity.first(),
68668             last = entity.isClosed() ? entity.nodes[entity.nodes.length - 2] : entity.last(),
68669             pseudoDirection = first < last,
68670             icon = pseudoDirection ? '#icon-forward' : '#icon-backward';
68671
68672         selection$$1.selectAll('.reverser-span')
68673             .text(t('inspector.check.reverser'))
68674             .call(svgIcon(icon, 'inline'));
68675
68676         return selection$$1;
68677     }
68678
68679
68680     var check = function(selection$$1) {
68681         checkImpliedYes();
68682         selection$$1.classed('checkselect', 'true');
68683
68684         label = selection$$1.selectAll('.preset-input-wrap')
68685             .data([0]);
68686
68687         var enter = label.enter()
68688             .append('label')
68689             .attr('class', 'preset-input-wrap');
68690
68691         enter
68692             .append('input')
68693             .property('indeterminate', field.type !== 'defaultCheck')
68694             .attr('type', 'checkbox')
68695             .attr('id', 'preset-input-' + field.id);
68696
68697         enter
68698             .append('span')
68699             .text(texts[0])
68700             .attr('class', 'value');
68701
68702         if (field.type === 'onewayCheck') {
68703             enter
68704                 .append('a')
68705                 .attr('id', 'preset-input-' + field.id + '-reverser')
68706                 .attr('class', 'reverser button' + (reverserHidden() ? ' hide' : ''))
68707                 .attr('href', '#')
68708                 .append('span')
68709                 .attr('class', 'reverser-span');
68710         }
68711
68712         label = label.merge(enter);
68713         input = label.selectAll('input');
68714         text$$1 = label.selectAll('span.value');
68715
68716         input
68717             .on('click', function() {
68718                 var t$$1 = {};
68719                 t$$1[field.key] = values$$1[(values$$1.indexOf(value) + 1) % values$$1.length];
68720                 dispatch$$1.call('change', this, t$$1);
68721                 event.stopPropagation();
68722             });
68723
68724         if (field.type === 'onewayCheck') {
68725             reverser = label.selectAll('.reverser');
68726
68727             reverser
68728                 .call(reverserSetText)
68729                 .on('click', function() {
68730                     event.preventDefault();
68731                     event.stopPropagation();
68732                     context.perform(
68733                         actionReverse(entityId),
68734                         t('operations.reverse.annotation')
68735                     );
68736                     select(this)
68737                         .call(reverserSetText);
68738                 });
68739         }
68740     };
68741
68742
68743     check.entity = function(_) {
68744         if (!arguments.length) return context.hasEntity(entityId);
68745         entityId = _.id;
68746         return check;
68747     };
68748
68749
68750     check.tags = function(tags) {
68751         checkImpliedYes();
68752         value = tags[field.key] && tags[field.key].toLowerCase();
68753
68754         if (field.type === 'onewayCheck' && (value === '1' || value === '-1')) {
68755             value = 'yes';
68756         }
68757
68758         input
68759             .property('indeterminate', field.type !== 'defaultCheck' && !value)
68760             .property('checked', value === 'yes');
68761
68762         text$$1
68763             .text(texts[values$$1.indexOf(value)]);
68764
68765         label
68766             .classed('set', !!value);
68767
68768         if (field.type === 'onewayCheck') {
68769             reverser
68770                 .classed('hide', reverserHidden())
68771                 .call(reverserSetText);
68772         }
68773     };
68774
68775
68776     check.focus = function() {
68777         input.node().focus();
68778     };
68779
68780     return utilRebind(check, dispatch$$1, 'on');
68781 }
68782
68783 function uiFieldCombo(field, context) {
68784     var dispatch$$1 = dispatch('change'),
68785         nominatim = services.geocoder,
68786         taginfo = services.taginfo,
68787         isMulti = (field.type === 'multiCombo'),
68788         isNetwork = (field.type === 'networkCombo'),
68789         isSemi = (field.type === 'semiCombo'),
68790         optstrings = field.strings && field.strings.options,
68791         optarray = field.options,
68792         snake_case = (field.snake_case || (field.snake_case === undefined)),
68793         combobox = d3combobox()
68794             .container(context.container())
68795             .minItems(isMulti || isSemi ? 1 : 2),
68796         comboData = [],
68797         multiData = [],
68798         container,
68799         input,
68800         entity,
68801         country;
68802
68803     // ensure multiCombo field.key ends with a ':'
68804     if (isMulti && field.key.match(/:$/) === null) {
68805         field.key += ':';
68806     }
68807
68808
68809     function snake(s) {
68810         return s.replace(/\s+/g, '_');
68811     }
68812
68813     function unsnake(s) {
68814         return s.replace(/_+/g, ' ');
68815     }
68816
68817     function clean(s) {
68818         return s.split(';')
68819             .map(function(s) { return s.trim(); })
68820             .join(';');
68821     }
68822
68823
68824     // returns the tag value for a display value
68825     // (for multiCombo, dval should be the key suffix, not the entire key)
68826     function tagValue(dval) {
68827         dval = clean(dval || '');
68828
68829         if (optstrings) {
68830             var match = lodash.find(comboData, function(o) {
68831                 return o.key && clean(o.value) === dval;
68832             });
68833             if (match) {
68834                 return match.key;
68835             }
68836         }
68837
68838         if (field.type === 'typeCombo' && !dval) {
68839             return 'yes';
68840         }
68841
68842         return (snake_case ? snake(dval) : dval) || undefined;
68843     }
68844
68845
68846     // returns the display value for a tag value
68847     // (for multiCombo, tval should be the key suffix, not the entire key)
68848     function displayValue(tval) {
68849         tval = tval || '';
68850
68851         if (optstrings) {
68852             var match = lodash.find(comboData, function(o) { return o.key === tval && o.value; });
68853             if (match) {
68854                 return match.value;
68855             }
68856         }
68857
68858         if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
68859             return '';
68860         }
68861
68862         return snake_case ? unsnake(tval) : tval;
68863     }
68864
68865
68866     function objectDifference(a, b) {
68867         return lodash.reject(a, function(d1) {
68868             return lodash.some(b, function(d2) { return d1.value === d2.value; });
68869         });
68870     }
68871
68872
68873     function initCombo(selection$$1, attachTo) {
68874         if (optstrings) {
68875             selection$$1.attr('readonly', 'readonly');
68876             selection$$1.call(combobox, attachTo);
68877             setStaticValues(setPlaceholder);
68878
68879         } else if (optarray) {
68880             selection$$1.call(combobox, attachTo);
68881             setStaticValues(setPlaceholder);
68882
68883         } else if (taginfo) {
68884             selection$$1.call(combobox.fetcher(setTaginfoValues), attachTo);
68885             setTaginfoValues('', setPlaceholder);
68886         }
68887     }
68888
68889
68890     function setStaticValues(callback) {
68891         if (!(optstrings || optarray)) return;
68892
68893         if (optstrings) {
68894             comboData = Object.keys(optstrings).map(function(k) {
68895                 var v = field.t('options.' + k, { 'default': optstrings[k] });
68896                 return {
68897                     key: k,
68898                     value: v,
68899                     title: v
68900                 };
68901             });
68902
68903         } else if (optarray) {
68904             comboData = optarray.map(function(k) {
68905                 var v = snake_case ? unsnake(k) : k;
68906                 return {
68907                     key: k,
68908                     value: v,
68909                     title: v
68910                 };
68911             });
68912         }
68913
68914         combobox.data(objectDifference(comboData, multiData));
68915         if (callback) callback(comboData);
68916     }
68917
68918
68919     function setTaginfoValues(q, callback) {
68920         var fn = isMulti ? 'multikeys' : 'values';
68921         var query = (isMulti ? field.key : '') + q;
68922         var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
68923         if (hasCountryPrefix) {
68924             query = country + ':';
68925         }
68926
68927         var params = {
68928             debounce: (q !== ''),
68929             key: field.key,
68930             query: query
68931         };
68932
68933         if (entity) {
68934             params.geometry = context.geometry(entity.id);
68935         }
68936
68937         taginfo[fn](params, function(err, data) {
68938             if (err) return;
68939             if (hasCountryPrefix) {
68940                 data = lodash.filter(data, function(d) {
68941                     return d.value.toLowerCase().indexOf(country + ':') === 0;
68942                 });
68943             }
68944
68945             comboData = lodash.map(data, function(d) {
68946                 var k = d.value;
68947                 if (isMulti) k = k.replace(field.key, '');
68948                 var v = snake_case ? unsnake(k) : k;
68949                 return {
68950                     key: k,
68951                     value: v,
68952                     title: isMulti ? v : d.title
68953                 };
68954             });
68955
68956             comboData = objectDifference(comboData, multiData);
68957             if (callback) callback(comboData);
68958         });
68959     }
68960
68961
68962     function setPlaceholder(d) {
68963         var ph;
68964
68965         if (isMulti || isSemi) {
68966             ph = field.placeholder() || t('inspector.add');
68967         } else {
68968             var vals = lodash.map(d, 'value').filter(function(s) { return s.length < 20; }),
68969                 placeholders = vals.length > 1 ? vals : lodash.map(d, 'key');
68970             ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
68971         }
68972
68973         if (ph.match(/(…|\.\.\.)$/) === null) {
68974             ph += '…';
68975         }
68976
68977         container.selectAll('input')
68978             .attr('placeholder', ph);
68979     }
68980
68981
68982     function change() {
68983         var val = tagValue(utilGetSetValue(input)),
68984             t$$1 = {};
68985
68986         if (isMulti || isSemi) {
68987             if (!val) return;
68988             container.classed('active', false);
68989             utilGetSetValue(input, '');
68990             if (isMulti) {
68991                 field.keys.push(field.key + val);
68992                 t$$1[field.key + val] = 'yes';
68993             } else if (isSemi) {
68994                 var arr = multiData.map(function(d) { return d.key; });
68995                 arr.push(val);
68996                 t$$1[field.key] = lodash.compact(lodash.uniq(arr)).join(';');
68997             }
68998             window.setTimeout(function() { input.node().focus(); }, 10);
68999
69000         } else {
69001             t$$1[field.key] = val;
69002         }
69003
69004         dispatch$$1.call('change', this, t$$1);
69005     }
69006
69007
69008     function removeMultikey(d) {
69009         event.stopPropagation();
69010         var t$$1 = {};
69011         if (isMulti) {
69012             t$$1[d.key] = undefined;
69013         } else if (isSemi) {
69014             lodash.remove(multiData, function(md) { return md.key === d.key; });
69015             var arr = multiData.map(function(md) { return md.key; });
69016             arr = lodash.compact(lodash.uniq(arr));
69017             t$$1[field.key] = arr.length ? arr.join(';') : undefined;
69018         }
69019         dispatch$$1.call('change', this, t$$1);
69020     }
69021
69022
69023     function combo(selection$$1) {
69024         if (isMulti || isSemi) {
69025             container = selection$$1.selectAll('ul').data([0]);
69026
69027             container = container.enter()
69028                 .append('ul')
69029                 .attr('class', 'form-field-multicombo')
69030                 .on('click', function() {
69031                     window.setTimeout(function() { input.node().focus(); }, 10);
69032                 })
69033                 .merge(container);
69034
69035         } else {
69036             container = selection$$1;
69037         }
69038
69039         input = container.selectAll('input')
69040             .data([0]);
69041
69042         input = input.enter()
69043             .append('input')
69044             .attr('type', 'text')
69045             .attr('id', 'preset-input-' + field.id)
69046             .call(utilNoAuto)
69047             .call(initCombo, selection$$1)
69048             .merge(input);
69049
69050         if (isNetwork && nominatim && entity) {
69051             var center = entity.extent(context.graph()).center();
69052             nominatim.countryCode(center, function (err, code) {
69053                 country = code;
69054             });
69055         }
69056
69057         input
69058             .on('change', change)
69059             .on('blur', change);
69060
69061         if (isMulti || isSemi) {
69062             combobox
69063                 .on('accept', function() {
69064                     input.node().blur();
69065                     input.node().focus();
69066                 });
69067
69068             input
69069                 .on('focus', function() { container.classed('active', true); });
69070         }
69071     }
69072
69073
69074     combo.tags = function(tags) {
69075         if (isMulti || isSemi) {
69076             multiData = [];
69077
69078             if (isMulti) {
69079                 // Build multiData array containing keys already set..
69080                 Object.keys(tags).forEach(function(key) {
69081                     if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
69082
69083                     var suffix = key.substring(field.key.length);
69084                     multiData.push({
69085                         key: key,
69086                         value: displayValue(suffix)
69087                     });
69088                 });
69089
69090                 // Set keys for form-field modified (needed for undo and reset buttons)..
69091                 field.keys = lodash.map(multiData, 'key');
69092
69093             } else if (isSemi) {
69094                 var arr = lodash.compact(lodash.uniq((tags[field.key] || '').split(';')));
69095                 multiData = arr.map(function(key) {
69096                     return {
69097                         key: key,
69098                         value: displayValue(key)
69099                     };
69100                 });
69101             }
69102
69103             // Exclude existing multikeys from combo options..
69104             var available = objectDifference(comboData, multiData);
69105             combobox.data(available);
69106
69107             // Hide 'Add' button if this field uses fixed set of
69108             // translateable optstrings and they're all currently used..
69109             container.selectAll('.combobox-input, .combobox-caret')
69110                 .classed('hide', optstrings && !available.length);
69111
69112
69113             // Render chips
69114             var chips = container.selectAll('.chips')
69115                 .data(multiData);
69116
69117             chips.exit()
69118                 .remove();
69119
69120             var enter = chips.enter()
69121                 .insert('li', 'input')
69122                 .attr('class', 'chips');
69123
69124             enter.append('span');
69125             enter.append('a');
69126
69127             chips = chips.merge(enter);
69128
69129             chips.select('span')
69130                 .text(function(d) { return d.value; });
69131
69132             chips.select('a')
69133                 .on('click', removeMultikey)
69134                 .attr('class', 'remove')
69135                 .text('×');
69136
69137         } else {
69138             utilGetSetValue(input, displayValue(tags[field.key]));
69139         }
69140     };
69141
69142
69143     combo.focus = function() {
69144         input.node().focus();
69145     };
69146
69147
69148     combo.entity = function(_) {
69149         if (!arguments.length) return entity;
69150         entity = _;
69151         return combo;
69152     };
69153
69154
69155     return utilRebind(combo, dispatch$$1, 'on');
69156 }
69157
69158 function uiFieldText(field, context) {
69159     var dispatch$$1 = dispatch('change'),
69160         nominatim = services.geocoder,
69161         input,
69162         entity;
69163
69164
69165     function i(selection$$1) {
69166         var fieldId = 'preset-input-' + field.id;
69167
69168         input = selection$$1.selectAll('input')
69169             .data([0]);
69170
69171         input = input.enter()
69172             .append('input')
69173             .attr('type', field.type)
69174             .attr('id', fieldId)
69175             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
69176             .call(utilNoAuto)
69177             .merge(input);
69178
69179         input
69180             .on('input', change(true))
69181             .on('blur', change())
69182             .on('change', change());
69183
69184         if (field.type === 'tel' && nominatim && entity) {
69185             var center = entity.extent(context.graph()).center();
69186             nominatim.countryCode(center, function (err, countryCode) {
69187                 if (err || !dataPhoneFormats[countryCode]) return;
69188                 selection$$1.selectAll('#' + fieldId)
69189                     .attr('placeholder', dataPhoneFormats[countryCode]);
69190             });
69191
69192         } else if (field.type === 'number') {
69193             var rtl = (textDirection === 'rtl');
69194
69195             input.attr('type', 'text');
69196
69197             var spinControl = selection$$1.selectAll('.spin-control')
69198                 .data([0]);
69199
69200             var enter = spinControl.enter()
69201                 .append('div')
69202                 .attr('class', 'spin-control');
69203
69204             enter
69205                 .append('button')
69206                 .datum(rtl ? 1 : -1)
69207                 .attr('class', rtl ? 'increment' : 'decrement')
69208                 .attr('tabindex', -1);
69209
69210             enter
69211                 .append('button')
69212                 .datum(rtl ? -1 : 1)
69213                 .attr('class', rtl ? 'decrement' : 'increment')
69214                 .attr('tabindex', -1);
69215
69216             spinControl = spinControl
69217                 .merge(enter);
69218
69219             spinControl.selectAll('button')
69220                 .on('click', function(d) {
69221                     event.preventDefault();
69222                     var num = parseInt(input.node().value || 0, 10);
69223                     if (!isNaN(num)) input.node().value = num + d;
69224                     change()();
69225                 });
69226         }
69227     }
69228
69229
69230     function change(onInput) {
69231         return function() {
69232             var t$$1 = {};
69233             t$$1[field.key] = utilGetSetValue(input) || undefined;
69234             dispatch$$1.call('change', this, t$$1, onInput);
69235         };
69236     }
69237
69238
69239     i.entity = function(_) {
69240         if (!arguments.length) return entity;
69241         entity = _;
69242         return i;
69243     };
69244
69245
69246     i.tags = function(tags) {
69247         utilGetSetValue(input, tags[field.key] || '');
69248     };
69249
69250
69251     i.focus = function() {
69252         var node = input.node();
69253         if (node) node.focus();
69254     };
69255
69256     return utilRebind(i, dispatch$$1, 'on');
69257 }
69258
69259 function uiFieldAccess(field, context) {
69260     var dispatch$$1 = dispatch('change'),
69261         items;
69262
69263     function access(selection$$1) {
69264         var wrap = selection$$1.selectAll('.preset-input-wrap')
69265             .data([0]);
69266
69267         wrap = wrap.enter()
69268             .append('div')
69269             .attr('class', 'cf preset-input-wrap')
69270             .append('ul')
69271             .merge(wrap);
69272
69273         var list = wrap.selectAll('ul')
69274             .data([0]);
69275
69276         list = list.enter()
69277             .append('ul')
69278             .merge(list);
69279
69280
69281         items = list.selectAll('li')
69282             .data(field.keys);
69283
69284         // Enter
69285         var enter = items.enter()
69286             .append('li')
69287             .attr('class', function(d) { return 'cf preset-access-' + d; });
69288
69289         enter
69290             .append('span')
69291             .attr('class', 'col6 label preset-label-access')
69292             .attr('for', function(d) { return 'preset-input-access-' + d; })
69293             .text(function(d) { return field.t('types.' + d); });
69294
69295         enter
69296             .append('div')
69297             .attr('class', 'col6 preset-input-access-wrap')
69298             .append('input')
69299             .attr('type', 'text')
69300             .attr('class', 'preset-input-access')
69301             .attr('id', function(d) { return 'preset-input-access-' + d; })
69302             .call(utilNoAuto)
69303             .each(function(d) {
69304                 select(this)
69305                     .call(d3combobox()
69306                         .container(context.container())
69307                         .data(access.options(d))
69308                     );
69309             });
69310
69311
69312         // Update
69313         items = items.merge(enter);
69314
69315         wrap.selectAll('.preset-input-access')
69316             .on('change', change)
69317             .on('blur', change);
69318     }
69319
69320
69321     function change(d) {
69322         var tag = {};
69323         tag[d] = utilGetSetValue(select(this)) || undefined;
69324         dispatch$$1.call('change', this, tag);
69325     }
69326
69327
69328     access.options = function(type) {
69329         var options = ['no', 'permissive', 'private', 'destination'];
69330
69331         if (type !== 'access') {
69332             options.unshift('yes');
69333             options.push('designated');
69334
69335             if (type === 'bicycle') {
69336                 options.push('dismount');
69337             }
69338         }
69339
69340         return options.map(function(option) {
69341             return {
69342                 title: field.t('options.' + option + '.description'),
69343                 value: option
69344             };
69345         });
69346     };
69347
69348
69349     var placeholders = {
69350         footway: {
69351             foot: 'designated',
69352             motor_vehicle: 'no'
69353         },
69354         steps: {
69355             foot: 'yes',
69356             motor_vehicle: 'no',
69357             bicycle: 'no',
69358             horse: 'no'
69359         },
69360         pedestrian: {
69361             foot: 'yes',
69362             motor_vehicle: 'no'
69363         },
69364         cycleway: {
69365             motor_vehicle: 'no',
69366             bicycle: 'designated'
69367         },
69368         bridleway: {
69369             motor_vehicle: 'no',
69370             horse: 'designated'
69371         },
69372         path: {
69373             foot: 'yes',
69374             motor_vehicle: 'no',
69375             bicycle: 'yes',
69376             horse: 'yes'
69377         },
69378         motorway: {
69379             foot: 'no',
69380             motor_vehicle: 'yes',
69381             bicycle: 'no',
69382             horse: 'no'
69383         },
69384         trunk: {
69385             motor_vehicle: 'yes'
69386         },
69387         primary: {
69388             foot: 'yes',
69389             motor_vehicle: 'yes',
69390             bicycle: 'yes',
69391             horse: 'yes'
69392         },
69393         secondary: {
69394             foot: 'yes',
69395             motor_vehicle: 'yes',
69396             bicycle: 'yes',
69397             horse: 'yes'
69398         },
69399         tertiary: {
69400             foot: 'yes',
69401             motor_vehicle: 'yes',
69402             bicycle: 'yes',
69403             horse: 'yes'
69404         },
69405         residential: {
69406             foot: 'yes',
69407             motor_vehicle: 'yes',
69408             bicycle: 'yes',
69409             horse: 'yes'
69410         },
69411         unclassified: {
69412             foot: 'yes',
69413             motor_vehicle: 'yes',
69414             bicycle: 'yes',
69415             horse: 'yes'
69416         },
69417         service: {
69418             foot: 'yes',
69419             motor_vehicle: 'yes',
69420             bicycle: 'yes',
69421             horse: 'yes'
69422         },
69423         motorway_link: {
69424             foot: 'no',
69425             motor_vehicle: 'yes',
69426             bicycle: 'no',
69427             horse: 'no'
69428         },
69429         trunk_link: {
69430             motor_vehicle: 'yes'
69431         },
69432         primary_link: {
69433             foot: 'yes',
69434             motor_vehicle: 'yes',
69435             bicycle: 'yes',
69436             horse: 'yes'
69437         },
69438         secondary_link: {
69439             foot: 'yes',
69440             motor_vehicle: 'yes',
69441             bicycle: 'yes',
69442             horse: 'yes'
69443         },
69444         tertiary_link: {
69445             foot: 'yes',
69446             motor_vehicle: 'yes',
69447             bicycle: 'yes',
69448             horse: 'yes'
69449         }
69450     };
69451
69452
69453     access.tags = function(tags) {
69454         utilGetSetValue(items.selectAll('.preset-input-access'),
69455             function(d) { return tags[d] || ''; })
69456             .attr('placeholder', function() {
69457                 return tags.access ? tags.access : field.placeholder();
69458             });
69459
69460         items.selectAll('#preset-input-access-access')
69461             .attr('placeholder', 'yes');
69462
69463         lodash.forEach(placeholders[tags.highway], function(v, k) {
69464             items.selectAll('#preset-input-access-' + k)
69465                 .attr('placeholder', function() { return (tags.access || v); });
69466         });
69467     };
69468
69469
69470     access.focus = function() {
69471         items.selectAll('.preset-input-access')
69472             .node().focus();
69473     };
69474
69475
69476     return utilRebind(access, dispatch$$1, 'on');
69477 }
69478
69479 function uiFieldAddress(field, context) {
69480     var dispatch$$1 = dispatch('init', 'change'),
69481         nominatim = services.geocoder,
69482         wrap = select(null),
69483         isInitialized = false,
69484         entity;
69485
69486     function getNearStreets() {
69487         var extent$$1 = entity.extent(context.graph()),
69488             l = extent$$1.center(),
69489             box = geoExtent$$1(l).padByMeters(200);
69490
69491         var streets = context.intersects(box)
69492             .filter(isAddressable)
69493             .map(function(d) {
69494                 var loc = context.projection([
69495                     (extent$$1[0][0] + extent$$1[1][0]) / 2,
69496                     (extent$$1[0][1] + extent$$1[1][1]) / 2]),
69497                     choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
69498                 return {
69499                     title: d.tags.name,
69500                     value: d.tags.name,
69501                     dist: choice.distance
69502                 };
69503             })
69504             .sort(function(a, b) {
69505                 return a.dist - b.dist;
69506             });
69507
69508         return lodash.uniqBy(streets, 'value');
69509
69510         function isAddressable(d) {
69511             return d.tags.highway && d.tags.name && d.type === 'way';
69512         }
69513     }
69514
69515
69516     function getNearCities() {
69517         var extent$$1 = entity.extent(context.graph()),
69518             l = extent$$1.center(),
69519             box = geoExtent$$1(l).padByMeters(200);
69520
69521         var cities = context.intersects(box)
69522             .filter(isAddressable)
69523             .map(function(d) {
69524                 return {
69525                     title: d.tags['addr:city'] || d.tags.name,
69526                     value: d.tags['addr:city'] || d.tags.name,
69527                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
69528                 };
69529             })
69530             .sort(function(a, b) {
69531                 return a.dist - b.dist;
69532             });
69533
69534         return lodash.uniqBy(cities, 'value');
69535
69536
69537         function isAddressable(d) {
69538             if (d.tags.name &&
69539                 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
69540                 return true;
69541
69542             if (d.tags.place && d.tags.name && (
69543                     d.tags.place === 'city' ||
69544                     d.tags.place === 'town' ||
69545                     d.tags.place === 'village'))
69546                 return true;
69547
69548             if (d.tags['addr:city']) return true;
69549
69550             return false;
69551         }
69552     }
69553
69554     function getNearValues(key) {
69555         var extent$$1 = entity.extent(context.graph()),
69556             l = extent$$1.center(),
69557             box = geoExtent$$1(l).padByMeters(200);
69558
69559         var results = context.intersects(box)
69560             .filter(function hasTag(d) {
69561                 return d.tags[key];
69562             })
69563             .map(function(d) {
69564                 return {
69565                     title: d.tags[key],
69566                     value: d.tags[key],
69567                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
69568                 };
69569             })
69570             .sort(function(a, b) {
69571                 return a.dist - b.dist;
69572             });
69573
69574         return lodash.uniqBy(results, 'value');
69575     }
69576
69577
69578     function initCallback(err, countryCode) {
69579         if (err) return;
69580
69581         var addressFormat = lodash.find(dataAddressFormats, function (a) {
69582             return a && a.countryCodes && lodash.includes(a.countryCodes, countryCode.toLowerCase());
69583         }) || lodash.first(dataAddressFormats);
69584
69585         var widths = addressFormat.widths || {
69586             housenumber: 1/3, street: 2/3,
69587             city: 2/3, state: 1/4, postcode: 1/3
69588         };
69589
69590         function row(r) {
69591             // Normalize widths.
69592             var total = lodash.reduce(r, function(sum$$1, field) {
69593                 return sum$$1 + (widths[field] || 0.5);
69594             }, 0);
69595
69596             return r.map(function (field) {
69597                 return {
69598                     id: field,
69599                     width: (widths[field] || 0.5) / total
69600                 };
69601             });
69602         }
69603
69604         wrap.selectAll('div.addr-row')
69605             .data(addressFormat.format)
69606             .enter()
69607             .append('div')
69608             .attr('class', 'addr-row')
69609             .selectAll('input')
69610             .data(row)
69611             .enter()
69612             .append('input')
69613             .property('type', 'text')
69614             .attr('placeholder', function (d) {
69615                 var localkey = d.id + '!' + countryCode.toLowerCase(),
69616                     tkey = field.strings.placeholders[localkey] ? localkey : d.id;
69617                 return field.t('placeholders.' + tkey);
69618             })
69619             .attr('class', function (d) { return 'addr-' + d.id; })
69620             .call(utilNoAuto)
69621             .style('width', function (d) { return d.width * 100 + '%'; });
69622
69623         // Update
69624
69625         // setup dropdowns for common address tags
69626         var dropdowns = addressFormat.dropdowns || [
69627             'city', 'county', 'country', 'district', 'hamlet',
69628             'neighbourhood', 'place', 'postcode', 'province',
69629             'quarter', 'state', 'street', 'subdistrict', 'suburb'
69630         ];
69631
69632         // If fields exist for any of these tags, create dropdowns to pick nearby values..
69633         dropdowns.forEach(function(tag) {
69634             var nearValues = (tag === 'street') ? getNearStreets
69635                     : (tag === 'city') ? getNearCities
69636                     : getNearValues;
69637
69638             wrap.selectAll('input.addr-' + tag)
69639                 .call(d3combobox()
69640                     .container(context.container())
69641                     .minItems(1)
69642                     .fetcher(function(value, callback) {
69643                         callback(nearValues('addr:' + tag));
69644                     })
69645                 );
69646         });
69647
69648         wrap.selectAll('input')
69649             .on('blur', change())
69650             .on('change', change());
69651
69652         wrap.selectAll('input:not(.combobox-input)')
69653             .on('input', change(true));
69654
69655         dispatch$$1.call('init');
69656         isInitialized = true;
69657     }
69658
69659
69660     function address(selection$$1) {
69661         isInitialized = false;
69662
69663         wrap = selection$$1.selectAll('.preset-input-wrap')
69664             .data([0]);
69665
69666         wrap = wrap.enter()
69667             .append('div')
69668             .attr('class', 'preset-input-wrap')
69669             .merge(wrap);
69670
69671         if (nominatim && entity) {
69672             var center = entity.extent(context.graph()).center();
69673             nominatim.countryCode(center, initCallback);
69674         }
69675     }
69676
69677
69678     function change(onInput) {
69679         return function() {
69680             var tags = {};
69681
69682             wrap.selectAll('input')
69683                 .each(function (field) {
69684                     tags['addr:' + field.id] = this.value || undefined;
69685                 });
69686
69687             dispatch$$1.call('change', this, tags, onInput);
69688         };
69689     }
69690
69691
69692     function updateTags(tags) {
69693         utilGetSetValue(wrap.selectAll('input'), function (field) {
69694             return tags['addr:' + field.id] || '';
69695         });
69696     }
69697
69698
69699     address.entity = function(_) {
69700         if (!arguments.length) return entity;
69701         entity = _;
69702         return address;
69703     };
69704
69705
69706     address.tags = function(tags) {
69707         if (isInitialized) {
69708             updateTags(tags);
69709         } else {
69710             dispatch$$1.on('init', function () {
69711                 dispatch$$1.on('init', null);
69712                 updateTags(tags);
69713             });
69714         }
69715     };
69716
69717
69718     address.focus = function() {
69719         var node = wrap.selectAll('input').node();
69720         if (node) node.focus();
69721     };
69722
69723
69724     return utilRebind(address, dispatch$$1, 'on');
69725 }
69726
69727 function uiFieldCycleway(field, context) {
69728     var dispatch$$1 = dispatch('change'),
69729         items = select(null);
69730
69731
69732     function cycleway(selection$$1) {
69733
69734         function stripcolon(s) {
69735             return s.replace(':', '');
69736         }
69737
69738
69739         var wrap = selection$$1.selectAll('.preset-input-wrap')
69740             .data([0]);
69741
69742         wrap = wrap.enter()
69743             .append('div')
69744             .attr('class', 'cf preset-input-wrap')
69745             .merge(wrap);
69746
69747
69748         var div = wrap.selectAll('ul')
69749             .data([0]);
69750
69751         div = div.enter()
69752             .append('ul')
69753             .merge(div);
69754
69755
69756         items = div.selectAll('li')
69757             .data(field.keys);
69758
69759         var enter = items.enter()
69760             .append('li')
69761             .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
69762
69763         enter
69764             .append('span')
69765             .attr('class', 'col6 label preset-label-cycleway')
69766             .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
69767             .text(function(d) { return field.t('types.' + d); });
69768
69769         enter
69770             .append('div')
69771             .attr('class', 'col6 preset-input-cycleway-wrap')
69772             .append('input')
69773             .attr('type', 'text')
69774             .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
69775             .call(utilNoAuto)
69776             .each(function(d) {
69777                 select(this)
69778                     .call(d3combobox()
69779                         .container(context.container())
69780                         .data(cycleway.options(d))
69781                     );
69782             });
69783
69784
69785         // Update
69786         wrap.selectAll('.preset-input-cycleway')
69787             .on('change', change)
69788             .on('blur', change);
69789     }
69790
69791
69792     function change() {
69793         var left = utilGetSetValue(select('.preset-input-cyclewayleft')),
69794             right = utilGetSetValue(select('.preset-input-cyclewayright')),
69795             tag = {};
69796
69797         if (left === 'none' || left === '') { left = undefined; }
69798         if (right === 'none' || right === '') { right = undefined; }
69799
69800         // Always set both left and right as changing one can affect the other
69801         tag = {
69802             cycleway: undefined,
69803             'cycleway:left': left,
69804             'cycleway:right': right
69805         };
69806
69807         // If the left and right tags match, use the cycleway tag to tag both
69808         // sides the same way
69809         if (left === right) {
69810             tag = {
69811                 cycleway: left,
69812                 'cycleway:left': undefined,
69813                 'cycleway:right': undefined
69814             };
69815         }
69816
69817         dispatch$$1.call('change', this, tag);
69818     }
69819
69820
69821     cycleway.options = function() {
69822         return keys(field.strings.options).map(function(option) {
69823             return {
69824                 title: field.t('options.' + option + '.description'),
69825                 value: option
69826             };
69827         });
69828     };
69829
69830
69831     cycleway.tags = function(tags) {
69832         utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
69833                 // If cycleway is set, always return that
69834                 if (tags.cycleway) {
69835                     return tags.cycleway;
69836                 }
69837                 return tags[d] || '';
69838             })
69839             .attr('placeholder', field.placeholder());
69840     };
69841
69842
69843     cycleway.focus = function() {
69844         items.selectAll('.preset-input-cycleway')
69845             .node().focus();
69846     };
69847
69848
69849     return utilRebind(cycleway, dispatch$$1, 'on');
69850 }
69851
69852 function uiFieldLanes(field, context) {
69853     var dispatch$$1 = dispatch('change'),
69854         LANE_WIDTH = 40,
69855         LANE_HEIGHT = 200,
69856         wayID,
69857         lanesData;
69858
69859     function lanes(selection$$1) {
69860         lanesData = context.entity(wayID).lanes();
69861
69862         if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
69863             selection$$1.call(lanes.off);
69864             return;
69865         }
69866
69867         var wrap = selection$$1.selectAll('.preset-input-wrap')
69868             .data([0]);
69869
69870         wrap = wrap.enter()
69871             .append('div')
69872             .attr('class', 'preset-input-wrap')
69873             .merge(wrap);
69874
69875         var surface =  wrap.selectAll('.surface')
69876             .data([0]);
69877
69878         var d = utilGetDimensions(wrap);
69879         var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
69880
69881         surface = surface.enter()
69882             .append('svg')
69883             .attr('width', d[0])
69884             .attr('height', 300)
69885             .attr('class', 'surface')
69886             .merge(surface);
69887
69888
69889         var lanesSelection = surface.selectAll('.lanes')
69890             .data([0]);
69891
69892         lanesSelection = lanesSelection.enter()
69893             .append('g')
69894             .attr('class', 'lanes')
69895             .merge(lanesSelection);
69896
69897         lanesSelection
69898             .attr('transform', function () {
69899                 return 'translate(' + (freeSpace / 2) + ', 0)';
69900             });
69901
69902
69903         var lane = lanesSelection.selectAll('.lane')
69904            .data(lanesData.lanes);
69905
69906         lane.exit()
69907             .remove();
69908
69909         var enter = lane.enter()
69910             .append('g')
69911             .attr('class', 'lane');
69912
69913         enter
69914             .append('g')
69915             .append('rect')
69916             .attr('y', 50)
69917             .attr('width', LANE_WIDTH)
69918             .attr('height', LANE_HEIGHT);
69919
69920         enter
69921             .append('g')
69922             .attr('class', 'forward')
69923             .append('text')
69924             .attr('y', 40)
69925             .attr('x', 14)
69926             .text('▲');
69927
69928         enter
69929             .append('g')
69930             .attr('class', 'bothways')
69931             .append('text')
69932             .attr('y', 40)
69933             .attr('x', 14)
69934             .text('▲▼');
69935
69936         enter
69937             .append('g')
69938             .attr('class', 'backward')
69939             .append('text')
69940             .attr('y', 40)
69941             .attr('x', 14)
69942             .text('▼');
69943
69944
69945         lane = lane
69946             .merge(enter);
69947
69948         lane
69949             .attr('transform', function(d) {
69950                 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
69951             });
69952
69953         lane.select('.forward')
69954             .style('visibility', function(d) {
69955                 return d.direction === 'forward' ? 'visible' : 'hidden';
69956             });
69957
69958         lane.select('.bothways')
69959             .style('visibility', function(d) {
69960                 return d.direction === 'bothways' ? 'visible' : 'hidden';
69961             });
69962
69963         lane.select('.backward')
69964             .style('visibility', function(d) {
69965                 return d.direction === 'backward' ? 'visible' : 'hidden';
69966             });
69967     }
69968
69969
69970     lanes.entity = function(_) {
69971         if (!wayID || wayID !== _.id) {
69972             wayID = _.id;
69973         }
69974     };
69975
69976     lanes.tags = function() {};
69977     lanes.focus = function() {};
69978     lanes.off = function() {};
69979
69980     return utilRebind(lanes, dispatch$$1, 'on');
69981 }
69982
69983 function uiFieldLocalized(field, context) {
69984     var dispatch$$1 = dispatch('change', 'input'),
69985         wikipedia = services.wikipedia,
69986         input = select(null),
69987         localizedInputs = select(null),
69988         wikiTitles,
69989         entity;
69990
69991
69992     function localized(selection$$1) {
69993         input = selection$$1.selectAll('.localized-main')
69994             .data([0]);
69995
69996         input = input.enter()
69997             .append('input')
69998             .attr('type', 'text')
69999             .attr('id', 'preset-input-' + field.id)
70000             .attr('class', 'localized-main')
70001             .attr('placeholder', field.placeholder())
70002             .call(utilNoAuto)
70003             .merge(input);
70004
70005         if (field.id === 'name') {
70006             var preset = context.presets().match(entity, context.graph());
70007             input
70008                 .call(d3combobox()
70009                     .container(context.container())
70010                     .fetcher(utilSuggestNames(preset, dataSuggestions))
70011                 );
70012         }
70013
70014         input
70015             .on('input', change(true))
70016             .on('blur', change())
70017             .on('change', change());
70018
70019
70020         var translateButton = selection$$1.selectAll('.localized-add')
70021             .data([0]);
70022
70023         translateButton = translateButton.enter()
70024             .append('button')
70025             .attr('class', 'button-input-action localized-add minor')
70026             .attr('tabindex', -1)
70027             .call(svgIcon('#icon-plus'))
70028             .call(tooltip()
70029                 .title(t('translate.translate'))
70030                 .placement('left'))
70031             .merge(translateButton);
70032
70033         translateButton
70034             .on('click', addNew);
70035
70036
70037         localizedInputs = selection$$1.selectAll('.localized-wrap')
70038             .data([0]);
70039
70040         localizedInputs = localizedInputs.enter().append('div')
70041             .attr('class', 'localized-wrap')
70042             .merge(localizedInputs);
70043     }
70044
70045
70046     function addNew() {
70047         event.preventDefault();
70048         var data$$1 = localizedInputs.selectAll('div.entry').data();
70049         var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
70050         var langExists = lodash.find(data$$1, function(datum) { return datum.lang === defaultLang;});
70051         var isLangEn = defaultLang.indexOf('en') > -1;
70052         if (isLangEn || langExists) {
70053             defaultLang = '';
70054         }
70055         data$$1.push({ lang: defaultLang, value: '' });
70056         localizedInputs.call(render, data$$1);
70057     }
70058
70059
70060     function change(onInput) {
70061         return function() {
70062             var t$$1 = {};
70063             t$$1[field.key] = utilGetSetValue(select(this)) || undefined;
70064             dispatch$$1.call('change', this, t$$1, onInput);
70065         };
70066     }
70067
70068
70069     function key(lang) {
70070         return field.key + ':' + lang;
70071     }
70072
70073
70074     function changeLang(d) {
70075         var lang = utilGetSetValue(select(this)),
70076             t$$1 = {},
70077             language = lodash.find(dataWikipedia, function(d) {
70078                 return d[0].toLowerCase() === lang.toLowerCase() ||
70079                     d[1].toLowerCase() === lang.toLowerCase();
70080             });
70081
70082         if (language) lang = language[2];
70083
70084         if (d.lang && d.lang !== lang) {
70085             t$$1[key(d.lang)] = undefined;
70086         }
70087
70088         var value = utilGetSetValue(select(this.parentNode)
70089             .selectAll('.localized-value'));
70090
70091         if (lang && value) {
70092             t$$1[key(lang)] = value;
70093         } else if (lang && wikiTitles && wikiTitles[d.lang]) {
70094             t$$1[key(lang)] = wikiTitles[d.lang];
70095         }
70096
70097         d.lang = lang;
70098         dispatch$$1.call('change', this, t$$1);
70099     }
70100
70101
70102     function changeValue(d) {
70103         if (!d.lang) return;
70104         var t$$1 = {};
70105         t$$1[key(d.lang)] = utilGetSetValue(select(this)) || undefined;
70106         dispatch$$1.call('change', this, t$$1);
70107     }
70108
70109
70110     function fetcher(value, cb) {
70111         var v = value.toLowerCase();
70112
70113         cb(dataWikipedia.filter(function(d) {
70114             return d[0].toLowerCase().indexOf(v) >= 0 ||
70115             d[1].toLowerCase().indexOf(v) >= 0 ||
70116             d[2].toLowerCase().indexOf(v) >= 0;
70117         }).map(function(d) {
70118             return { value: d[1] };
70119         }));
70120     }
70121
70122
70123     function render(selection$$1, data$$1) {
70124         var wraps = selection$$1.selectAll('div.entry').
70125             data(data$$1, function(d) { return d.lang; });
70126
70127         wraps.exit()
70128             .transition()
70129             .duration(200)
70130             .style('max-height','0px')
70131             .style('opacity', '0')
70132             .style('top','-10px')
70133             .remove();
70134
70135         var innerWrap = wraps.enter()
70136             .insert('div', ':first-child');
70137
70138         innerWrap.attr('class', 'entry')
70139             .each(function() {
70140                 var wrap = select(this);
70141                 var langcombo = d3combobox()
70142                     .container(context.container())
70143                     .fetcher(fetcher)
70144                     .minItems(0);
70145
70146                 var label = wrap
70147                     .append('label')
70148                     .attr('class','form-label')
70149                     .text(t('translate.localized_translation_label'))
70150                     .attr('for','localized-lang');
70151
70152                 label
70153                     .append('button')
70154                     .attr('class', 'minor remove')
70155                     .on('click', function(d){
70156                         event.preventDefault();
70157                         var t$$1 = {};
70158                         t$$1[key(d.lang)] = undefined;
70159                         dispatch$$1.call('change', this, t$$1);
70160                         select(this.parentNode.parentNode)
70161                             .style('top','0')
70162                             .style('max-height','240px')
70163                             .transition()
70164                             .style('opacity', '0')
70165                             .style('max-height','0px')
70166                             .remove();
70167                     })
70168                     .call(svgIcon('#operation-delete'));
70169
70170                 wrap
70171                     .append('input')
70172                     .attr('class', 'localized-lang')
70173                     .attr('type', 'text')
70174                     .attr('placeholder',t('translate.localized_translation_language'))
70175                     .on('blur', changeLang)
70176                     .on('change', changeLang)
70177                     .call(langcombo);
70178
70179                 wrap
70180                     .append('input')
70181                     .on('blur', changeValue)
70182                     .on('change', changeValue)
70183                     .attr('type', 'text')
70184                     .attr('placeholder', t('translate.localized_translation_name'))
70185                     .attr('class', 'localized-value');
70186             });
70187
70188         innerWrap
70189             .style('margin-top', '0px')
70190             .style('max-height', '0px')
70191             .style('opacity', '0')
70192             .transition()
70193             .duration(200)
70194             .style('margin-top', '10px')
70195             .style('max-height', '240px')
70196             .style('opacity', '1')
70197             .on('end', function() {
70198                 select(this)
70199                     .style('max-height', '')
70200                     .style('overflow', 'visible');
70201             });
70202
70203
70204         var entry = selection$$1.selectAll('.entry');
70205
70206         utilGetSetValue(entry.select('.localized-lang'), function(d) {
70207                 var lang = lodash.find(dataWikipedia, function(lang) { return lang[2] === d.lang; });
70208                 return lang ? lang[1] : d.lang;
70209             });
70210
70211         utilGetSetValue(entry.select('.localized-value'),
70212             function(d) { return d.value; });
70213     }
70214
70215
70216     localized.tags = function(tags) {
70217         // Fetch translations from wikipedia
70218         if (tags.wikipedia && !wikiTitles) {
70219             wikiTitles = {};
70220             var wm = tags.wikipedia.match(/([^:]+):(.+)/);
70221             if (wm && wm[0] && wm[1]) {
70222                 wikipedia.translations(wm[1], wm[2], function(d) {
70223                     wikiTitles = d;
70224                 });
70225             }
70226         }
70227
70228         utilGetSetValue(input, tags[field.key] || '');
70229
70230         var postfixed = [], k, m;
70231         for (k in tags) {
70232             m = k.match(/^(.*):([a-zA-Z_-]+)$/);
70233             if (m && m[1] === field.key && m[2]) {
70234                 postfixed.push({ lang: m[2], value: tags[k] });
70235             }
70236         }
70237
70238         localizedInputs.call(render, postfixed.reverse());
70239     };
70240
70241
70242     localized.focus = function() {
70243         input.node().focus();
70244     };
70245
70246
70247     localized.entity = function(_) {
70248         if (!arguments.length) return entity;
70249         entity = _;
70250         return localized;
70251     };
70252
70253     return utilRebind(localized, dispatch$$1, 'on');
70254 }
70255
70256 function uiFieldMaxspeed(field, context) {
70257     var dispatch$$1 = dispatch('change'),
70258         entity,
70259         isImperial,
70260         unitInput = select(null),
70261         input = select(null),
70262         combobox;
70263
70264     var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
70265         imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
70266
70267
70268     function maxspeed(selection$$1) {
70269         combobox = d3combobox()
70270             .container(context.container());
70271
70272         var unitCombobox = d3combobox()
70273             .container(context.container())
70274             .data(['km/h', 'mph'].map(comboValues));
70275
70276         input = selection$$1.selectAll('#preset-input-' + field.id)
70277             .data([0]);
70278
70279         input = input.enter()
70280             .append('input')
70281             .attr('type', 'text')
70282             .attr('id', 'preset-input-' + field.id)
70283             .attr('placeholder', field.placeholder())
70284             .call(utilNoAuto)
70285             .call(combobox)
70286             .merge(input);
70287
70288         input
70289             .on('change', change)
70290             .on('blur', change);
70291
70292         var childNodes = context.graph().childNodes(context.entity(entity.id)),
70293             loc = childNodes[~~(childNodes.length/2)].loc;
70294
70295         isImperial = lodash.some(dataImperial.features, function(f) {
70296             return lodash.some(f.geometry.coordinates, function(d) {
70297                 return geoPointInPolygon(loc, d);
70298             });
70299         });
70300
70301         unitInput = selection$$1.selectAll('input.maxspeed-unit')
70302             .data([0]);
70303
70304         unitInput = unitInput.enter()
70305             .append('input')
70306             .attr('type', 'text')
70307             .attr('class', 'maxspeed-unit')
70308             .call(unitCombobox)
70309             .merge(unitInput);
70310
70311         unitInput
70312             .on('blur', changeUnits)
70313             .on('change', changeUnits);
70314
70315
70316         function changeUnits() {
70317             isImperial = utilGetSetValue(unitInput) === 'mph';
70318             utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
70319             setSuggestions();
70320             change();
70321         }
70322     }
70323
70324
70325     function setSuggestions() {
70326         combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
70327         utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
70328     }
70329
70330
70331     function comboValues(d) {
70332         return {
70333             value: d.toString(),
70334             title: d.toString()
70335         };
70336     }
70337
70338
70339     function change() {
70340         var tag = {},
70341             value = utilGetSetValue(input);
70342
70343         if (!value) {
70344             tag[field.key] = undefined;
70345         } else if (isNaN(value) || !isImperial) {
70346             tag[field.key] = value;
70347         } else {
70348             tag[field.key] = value + ' mph';
70349         }
70350
70351         dispatch$$1.call('change', this, tag);
70352     }
70353
70354
70355     maxspeed.tags = function(tags) {
70356         var value = tags[field.key];
70357
70358         if (value && value.indexOf('mph') >= 0) {
70359             value = parseInt(value, 10);
70360             isImperial = true;
70361         } else if (value) {
70362             isImperial = false;
70363         }
70364
70365         setSuggestions();
70366         utilGetSetValue(input, value || '');
70367     };
70368
70369
70370     maxspeed.focus = function() {
70371         input.node().focus();
70372     };
70373
70374
70375     maxspeed.entity = function(_) {
70376         entity = _;
70377     };
70378
70379
70380     return utilRebind(maxspeed, dispatch$$1, 'on');
70381 }
70382
70383 function uiFieldRadio(field, context) {
70384     var dispatch$$1 = dispatch('change'),
70385         placeholder = select(null),
70386         wrap = select(null),
70387         labels = select(null),
70388         radios = select(null),
70389         typeField,
70390         layerField,
70391         oldType = {},
70392         entity;
70393
70394
70395     function selectedKey() {
70396         var selector$$1 = '.form-field-structure .toggle-list label.active input',
70397             node = selectAll(selector$$1);
70398         return !node.empty() && node.datum();
70399     }
70400
70401
70402     function radio(selection$$1) {
70403         selection$$1.classed('preset-radio', true);
70404
70405         wrap = selection$$1.selectAll('.preset-input-wrap')
70406             .data([0]);
70407
70408         var enter = wrap.enter()
70409             .append('div')
70410             .attr('class', 'preset-input-wrap toggle-list');
70411
70412         enter
70413             .append('span')
70414             .attr('class', 'placeholder');
70415
70416         wrap = wrap
70417             .merge(enter);
70418
70419
70420         placeholder = wrap.selectAll('.placeholder');
70421
70422         labels = wrap.selectAll('label')
70423             .data(field.options || field.keys);
70424
70425         enter = labels.enter()
70426             .append('label');
70427
70428         enter
70429             .append('input')
70430             .attr('type', 'radio')
70431             .attr('name', field.id)
70432             .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
70433             .attr('checked', false);
70434
70435         enter
70436             .append('span')
70437             .text(function(d) { return field.t('options.' + d, { 'default': d }); });
70438
70439         labels = labels
70440             .merge(enter);
70441
70442         radios = labels.selectAll('input')
70443             .on('change', changeRadio);
70444
70445     }
70446
70447
70448     function structureExtras(selection$$1, tags) {
70449         var selected = selectedKey(),
70450             type = context.presets().field(selected),
70451             layer = context.presets().field('layer'),
70452             showLayer = (selected === 'bridge' || selected === 'tunnel');
70453
70454
70455         var extrasWrap = selection$$1.selectAll('.structure-extras-wrap')
70456                 .data(selected ? [0] : []);
70457
70458         extrasWrap.exit()
70459             .remove();
70460
70461         extrasWrap = extrasWrap.enter()
70462             .append('div')
70463             .attr('class', 'structure-extras-wrap')
70464             .merge(extrasWrap);
70465
70466         var list = extrasWrap.selectAll('ul')
70467             .data([0]);
70468
70469         list = list.enter()
70470             .append('ul')
70471             .merge(list);
70472
70473
70474         // Type
70475         if (type) {
70476             if (!typeField || typeField.id !== selected) {
70477                 typeField = uiField(context, type, entity, { wrap: false })
70478                     .on('change', changeType);
70479             }
70480             typeField.tags(tags);
70481         } else {
70482             typeField = null;
70483         }
70484
70485         var typeItem = list.selectAll('.structure-type-item')
70486             .data(typeField ? [typeField] : [], function(d) { return d.id; });
70487
70488         // Exit
70489         typeItem.exit()
70490             .remove();
70491
70492         // Enter
70493         var typeEnter = typeItem.enter()
70494             .insert('li', ':first-child')
70495             .attr('class', 'cf structure-type-item');
70496
70497         typeEnter
70498             .append('span')
70499             .attr('class', 'col6 label structure-label-type')
70500             .attr('for', 'preset-input-' + selected)
70501             .text(t('inspector.radio.structure.type'));
70502
70503         typeEnter
70504             .append('div')
70505             .attr('class', 'col6 structure-input-type-wrap');
70506
70507         // Update
70508         typeItem = typeItem
70509             .merge(typeEnter);
70510
70511         if (typeField) {
70512             typeItem.selectAll('.structure-input-type-wrap')
70513                 .call(typeField.render);
70514         }
70515
70516
70517         // Layer
70518         if (layer && showLayer) {
70519             if (!layerField) {
70520                 layerField = uiField(context, layer, entity, { wrap: false })
70521                     .on('change', changeLayer);
70522             }
70523             layerField.tags(tags);
70524         } else {
70525             layerField = null;
70526         }
70527
70528         var layerItem = list.selectAll('.structure-layer-item')
70529             .data(layerField ? [layerField] : []);
70530
70531         // Exit
70532         layerItem.exit()
70533             .remove();
70534
70535         // Enter
70536         var layerEnter = layerItem.enter()
70537             .append('li')
70538             .attr('class', 'cf structure-layer-item');
70539
70540         layerEnter
70541             .append('span')
70542             .attr('class', 'col6 label structure-label-layer')
70543             .attr('for', 'preset-input-layer')
70544             .text(t('inspector.radio.structure.layer'));
70545
70546         layerEnter
70547             .append('div')
70548             .attr('class', 'col6 structure-input-layer-wrap');
70549
70550         // Update
70551         layerItem = layerItem
70552             .merge(layerEnter);
70553
70554         if (layerField) {
70555             layerItem.selectAll('.structure-input-layer-wrap')
70556                 .call(layerField.render);
70557         }
70558     }
70559
70560
70561     function changeType(t$$1, onInput) {
70562         var key = selectedKey();
70563         if (!key) return;
70564
70565         var val = t$$1[key];
70566         if (val !== 'no') oldType[key] = val;
70567         dispatch$$1.call('change', this, t$$1, onInput);
70568     }
70569
70570
70571     function changeLayer(t$$1, onInput) {
70572         if (t$$1.layer === '0') {
70573             t$$1.layer = undefined;
70574         }
70575         dispatch$$1.call('change', this, t$$1, onInput);
70576     }
70577
70578
70579     function changeRadio() {
70580         var t$$1 = {},
70581             activeKey;
70582
70583         if (field.key) {
70584             t$$1[field.key] = undefined;
70585         }
70586
70587         radios.each(function(d) {
70588             var active$$1 = select(this).property('checked');
70589             if (active$$1) activeKey = d;
70590
70591             if (field.key) {
70592                 if (active$$1) t$$1[field.key] = d;
70593             } else {
70594                 var val = oldType[activeKey] || 'yes';
70595                 t$$1[d] = active$$1 ? val : undefined;
70596             }
70597         });
70598
70599         if (field.type === 'structureRadio') {
70600             if (activeKey === 'bridge') {
70601                 t$$1.layer = '1';
70602             } else if (activeKey === 'tunnel') {
70603                 t$$1.layer = '-1';
70604             } else {
70605                 t$$1.layer = undefined;
70606             }
70607         }
70608
70609         dispatch$$1.call('change', this, t$$1);
70610     }
70611
70612
70613     radio.tags = function(tags) {
70614         function checked(d) {
70615             if (field.key) {
70616                 return tags[field.key] === d;
70617             } else {
70618                 return !!(tags[d] && tags[d].toLowerCase() !== 'no');
70619             }
70620         }
70621
70622         labels.classed('active', checked);
70623         radios.property('checked', checked);
70624
70625         var selection$$1 = radios.filter(function() { return this.checked; });
70626
70627         if (selection$$1.empty()) {
70628             placeholder.text(t('inspector.none'));
70629         } else {
70630             placeholder.text(selection$$1.attr('value'));
70631             oldType[selection$$1.datum()] = tags[selection$$1.datum()];
70632         }
70633
70634         if (field.type === 'structureRadio') {
70635             wrap.call(structureExtras, tags);
70636         }
70637     };
70638
70639
70640     radio.focus = function() {
70641         radios.node().focus();
70642     };
70643
70644
70645     radio.entity = function(_) {
70646         if (!arguments.length) return entity;
70647         entity = _;
70648         oldType = {};
70649         return radio;
70650     };
70651
70652
70653     return utilRebind(radio, dispatch$$1, 'on');
70654 }
70655
70656 function uiFieldRestrictions(field, context) {
70657     var dispatch$$1 = dispatch('change'),
70658         breathe = behaviorBreathe(context),
70659         hover = behaviorHover(context),
70660         initialized = false,
70661         vertexID,
70662         fromNodeID;
70663
70664
70665     function restrictions(selection$$1) {
70666         // if form field is hidden or has detached from dom, clean up.
70667         if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
70668             selection$$1.call(restrictions.off);
70669             return;
70670         }
70671
70672         var wrap = selection$$1.selectAll('.preset-input-wrap')
70673             .data([0]);
70674
70675         var enter = wrap.enter()
70676             .append('div')
70677             .attr('class', 'preset-input-wrap');
70678
70679         enter
70680             .append('div')
70681             .attr('class', 'restriction-help');
70682
70683
70684         var intersection = osmIntersection(context.graph(), vertexID),
70685             graph = intersection.graph,
70686             vertex = graph.entity(vertexID),
70687             filter = utilFunctor(true),
70688             extent$$1 = geoExtent$$1(),
70689             projection$$1 = geoRawMercator();
70690
70691         var d = utilGetDimensions(wrap.merge(enter)),
70692             c = [d[0] / 2, d[1] / 2],
70693             z = 24;
70694
70695         projection$$1
70696             .scale(256 * Math.pow(2, z) / (2 * Math.PI));
70697
70698         var s = projection$$1(vertex.loc);
70699
70700         projection$$1
70701             .translate([c[0] - s[0], c[1] - s[1]])
70702             .clipExtent([[0, 0], d]);
70703
70704         var drawLayers = svgLayers(projection$$1, context).only('osm').dimensions(d),
70705             drawVertices = svgVertices$$1(projection$$1, context),
70706             drawLines = svgLines$$1(projection$$1, context),
70707             drawTurns = svgTurns(projection$$1, context);
70708
70709         enter
70710             .call(drawLayers);
70711
70712         wrap = wrap
70713             .merge(enter);
70714
70715         var surface = wrap.selectAll('.surface');
70716
70717         if (!enter.empty()) {
70718             initialized = true;
70719             surface
70720                 .call(breathe)
70721                 .call(hover);
70722         }
70723
70724         surface
70725             .call(utilSetDimensions, d)
70726             .call(drawVertices, graph, [vertex], filter, extent$$1, z)
70727             .call(drawLines, graph, intersection.ways, filter)
70728             .call(drawTurns, graph, intersection.turns(fromNodeID));
70729
70730         surface
70731             .on('click.restrictions', click)
70732             .on('mouseover.restrictions', mouseover)
70733             .on('mouseout.restrictions', mouseout);
70734
70735         surface
70736             .selectAll('.selected')
70737             .classed('selected', false);
70738
70739         if (fromNodeID) {
70740             surface
70741                 .selectAll('.' + intersection.highways[fromNodeID].id)
70742                 .classed('selected', true);
70743         }
70744
70745         mouseout();
70746
70747         context.history()
70748             .on('change.restrictions', render);
70749
70750         select(window)
70751             .on('resize.restrictions', function() {
70752                 utilSetDimensions(wrap, null);
70753                 render();
70754             });
70755
70756
70757         function click() {
70758             surface
70759                 .call(breathe.off)
70760                 .call(breathe);
70761
70762             var datum = event.target.__data__;
70763             if (datum instanceof osmEntity$$1) {
70764                 fromNodeID = intersection.adjacentNodeId(datum.id);
70765                 render();
70766             } else if (datum instanceof osmTurn) {
70767                 if (datum.restriction) {
70768                     context.perform(
70769                         actionUnrestrictTurn(datum, projection$$1),
70770                         t('operations.restriction.annotation.delete')
70771                     );
70772                 } else {
70773                     context.perform(
70774                         actionRestrictTurn(datum, projection$$1),
70775                         t('operations.restriction.annotation.create')
70776                     );
70777                 }
70778             }
70779         }
70780
70781
70782         function mouseover() {
70783             var datum = event.target.__data__;
70784             if (datum instanceof osmTurn) {
70785                 var graph = context.graph(),
70786                     presets = context.presets(),
70787                     preset;
70788
70789                 if (datum.restriction) {
70790                     preset = presets.match(graph.entity(datum.restriction), graph);
70791                 } else {
70792                     preset = presets.item('type/restriction/' +
70793                         osmInferRestriction(
70794                             graph,
70795                             datum.from,
70796                             datum.via,
70797                             datum.to,
70798                             projection$$1
70799                         )
70800                     );
70801                 }
70802
70803                 wrap.selectAll('.restriction-help')
70804                     .text(t('operations.restriction.help.' +
70805                         (datum.restriction ? 'toggle_off' : 'toggle_on'),
70806                         { restriction: preset.name() })
70807                     );
70808             }
70809         }
70810
70811
70812         function mouseout() {
70813             wrap.selectAll('.restriction-help')
70814                 .text(t('operations.restriction.help.' +
70815                     (fromNodeID ? 'toggle' : 'select'))
70816                 );
70817         }
70818
70819
70820         function render() {
70821             if (context.hasEntity(vertexID)) {
70822                 restrictions(selection$$1);
70823             }
70824         }
70825     }
70826
70827
70828     restrictions.entity = function(_) {
70829         if (!vertexID || vertexID !== _.id) {
70830             fromNodeID = null;
70831             vertexID = _.id;
70832         }
70833     };
70834
70835
70836     restrictions.tags = function() {};
70837     restrictions.focus = function() {};
70838
70839
70840     restrictions.off = function(selection$$1) {
70841         if (!initialized) return;
70842
70843         selection$$1.selectAll('.surface')
70844             .call(hover.off)
70845             .call(breathe.off)
70846             .on('click.restrictions', null)
70847             .on('mouseover.restrictions', null)
70848             .on('mouseout.restrictions', null);
70849
70850         context.history()
70851             .on('change.restrictions', null);
70852
70853         select(window)
70854             .on('resize.restrictions', null);
70855     };
70856
70857
70858     return utilRebind(restrictions, dispatch$$1, 'on');
70859 }
70860
70861 function uiFieldTextarea(field) {
70862     var dispatch$$1 = dispatch('change'),
70863         input = select(null);
70864
70865
70866     function textarea(selection$$1) {
70867         input = selection$$1.selectAll('textarea')
70868             .data([0]);
70869
70870         input = input.enter()
70871             .append('textarea')
70872             .attr('id', 'preset-input-' + field.id)
70873             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
70874             .attr('maxlength', 255)
70875             .call(utilNoAuto)
70876             .on('input', change(true))
70877             .on('blur', change())
70878             .on('change', change())
70879             .merge(input);
70880     }
70881
70882
70883     function change(onInput) {
70884         return function() {
70885             var t$$1 = {};
70886             t$$1[field.key] = utilGetSetValue(input) || undefined;
70887             dispatch$$1.call('change', this, t$$1, onInput);
70888         };
70889     }
70890
70891
70892     textarea.tags = function(tags) {
70893         utilGetSetValue(input, tags[field.key] || '');
70894     };
70895
70896
70897     textarea.focus = function() {
70898         input.node().focus();
70899     };
70900
70901
70902     return utilRebind(textarea, dispatch$$1, 'on');
70903 }
70904
70905 function uiFieldWikipedia(field, context) {
70906     var dispatch$$1 = dispatch('change'),
70907         wikipedia = services.wikipedia,
70908         wikidata = services.wikidata,
70909         link$$1 = select(null),
70910         lang = select(null),
70911         title = select(null),
70912         wikiURL = '',
70913         entity;
70914
70915
70916     function wiki(selection$$1) {
70917         var langcombo = d3combobox()
70918             .container(context.container())
70919             .fetcher(function(value, cb) {
70920                 var v = value.toLowerCase();
70921
70922                 cb(dataWikipedia.filter(function(d) {
70923                     return d[0].toLowerCase().indexOf(v) >= 0 ||
70924                         d[1].toLowerCase().indexOf(v) >= 0 ||
70925                         d[2].toLowerCase().indexOf(v) >= 0;
70926                 }).map(function(d) {
70927                     return { value: d[1] };
70928                 }));
70929             });
70930
70931         var titlecombo = d3combobox()
70932             .container(context.container())
70933             .fetcher(function(value, cb) {
70934                 if (!value) {
70935                     value = context.entity(entity.id).tags.name || '';
70936                 }
70937
70938                 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
70939                 searchfn(language()[2], value, function(query, data$$1) {
70940                     cb(data$$1.map(function(d) {
70941                         return { value: d };
70942                     }));
70943                 });
70944             });
70945
70946
70947         lang = selection$$1.selectAll('input.wiki-lang')
70948             .data([0]);
70949
70950         lang = lang.enter()
70951             .append('input')
70952             .attr('type', 'text')
70953             .attr('class', 'wiki-lang')
70954             .attr('placeholder', t('translate.localized_translation_language'))
70955             .call(utilNoAuto)
70956             .merge(lang);
70957
70958         utilGetSetValue(lang, language()[1]);
70959
70960         lang
70961             .call(langcombo)
70962             .on('blur', changeLang)
70963             .on('change', changeLang);
70964
70965
70966         title = selection$$1.selectAll('input.wiki-title')
70967             .data([0]);
70968
70969         title = title.enter()
70970             .append('input')
70971             .attr('type', 'text')
70972             .attr('class', 'wiki-title')
70973             .attr('id', 'preset-input-' + field.id)
70974             .call(utilNoAuto)
70975             .merge(title);
70976
70977         title
70978             .call(titlecombo)
70979             .on('blur', blur)
70980             .on('change', change);
70981
70982
70983         link$$1 = selection$$1.selectAll('.wiki-link')
70984             .data([0]);
70985
70986         link$$1 = link$$1.enter()
70987             .append('button')
70988             .attr('class', 'button-input-action wiki-link minor')
70989             .attr('tabindex', -1)
70990             .call(svgIcon('#icon-out-link'))
70991             .merge(link$$1);
70992
70993         link$$1
70994             .on('click', function() {
70995                 event.preventDefault();
70996                 if (wikiURL) window.open(wikiURL, '_blank');
70997             });
70998     }
70999
71000
71001     function language() {
71002         var value = utilGetSetValue(lang).toLowerCase();
71003         var locale = utilDetect().locale.toLowerCase();
71004         var localeLanguage;
71005         return lodash.find(dataWikipedia, function(d) {
71006             if (d[2] === locale) localeLanguage = d;
71007             return d[0].toLowerCase() === value ||
71008                 d[1].toLowerCase() === value ||
71009                 d[2] === value;
71010         }) || localeLanguage || ['English', 'English', 'en'];
71011     }
71012
71013
71014     function changeLang() {
71015         utilGetSetValue(lang, language()[1]);
71016         change(true);
71017     }
71018
71019
71020     function blur() {
71021         change(true);
71022     }
71023
71024
71025     function change(skipWikidata) {
71026         var value = utilGetSetValue(title),
71027             m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
71028             l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
71029             syncTags = {};
71030
71031         if (l) {
71032             // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
71033             value = decodeURIComponent(m[2]).replace(/_/g, ' ');
71034             if (m[3]) {
71035                 var anchor;
71036                 try {
71037                     // Best-effort `anchordecode:` implementation
71038                     anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
71039                 } catch (e) {
71040                     anchor = decodeURIComponent(m[3]);
71041                 }
71042                 value += '#' + anchor.replace(/_/g, ' ');
71043             }
71044             value = value.slice(0, 1).toUpperCase() + value.slice(1);
71045             utilGetSetValue(lang, l[1]);
71046             utilGetSetValue(title, value);
71047         }
71048
71049         if (value) {
71050             syncTags.wikipedia = language()[2] + ':' + value;
71051         } else {
71052             syncTags.wikipedia = undefined;
71053             syncTags.wikidata = undefined;
71054         }
71055
71056         dispatch$$1.call('change', this, syncTags);
71057
71058
71059         if (skipWikidata || !value || !language()[2]) return;
71060
71061         // attempt asynchronous update of wikidata tag..
71062         var initGraph = context.graph(),
71063             initEntityId = entity.id;
71064
71065         wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
71066             // If graph has changed, we can't apply this update.
71067             if (context.graph() !== initGraph) return;
71068
71069             if (!data$$1 || !Object.keys(data$$1).length) return;
71070
71071             var qids = Object.keys(data$$1);
71072             var value = qids && lodash.find(qids, function(id) { return id.match(/^Q\d+$/); });
71073             var currTags = lodash.clone(context.entity(initEntityId).tags);
71074
71075             currTags.wikidata = value;
71076
71077             // Coalesce the update of wikidata tag into the previous tag change
71078             context.overwrite(
71079                 actionChangeTags(initEntityId, currTags),
71080                 context.history().undoAnnotation()
71081             );
71082
71083             // do not dispatch.call('change') here, because entity_editor
71084             // changeTags() is not intended to be called asynchronously
71085         });
71086     }
71087
71088
71089     wiki.tags = function(tags) {
71090         var value = tags[field.key] || '',
71091             m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
71092             l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
71093             anchor = m && m[3];
71094
71095         // value in correct format
71096         if (l) {
71097             utilGetSetValue(lang, l[1]);
71098             utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
71099             if (anchor) {
71100                 try {
71101                     // Best-effort `anchorencode:` implementation
71102                     anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
71103                 } catch (e) {
71104                     anchor = anchor.replace(/ /g, '_');
71105                 }
71106             }
71107             wikiURL = 'https://' + m[1] + '.wikipedia.org/wiki/' +
71108                 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : '');
71109
71110         // unrecognized value format
71111         } else {
71112             utilGetSetValue(title, value);
71113             if (value && value !== '') {
71114                 utilGetSetValue(lang, '');
71115                 wikiURL = 'https://en.wikipedia.org/wiki/Special:Search?search=' + value;
71116             } else {
71117                 wikiURL = '';
71118             }
71119         }
71120     };
71121
71122
71123     wiki.entity = function(_) {
71124         if (!arguments.length) return entity;
71125         entity = _;
71126         return wiki;
71127     };
71128
71129
71130     wiki.focus = function() {
71131         title.node().focus();
71132     };
71133
71134
71135     return utilRebind(wiki, dispatch$$1, 'on');
71136 }
71137
71138 var uiFields = {
71139     access: uiFieldAccess,
71140     address: uiFieldAddress,
71141     check: uiFieldCheck,
71142     combo: uiFieldCombo,
71143     cycleway: uiFieldCycleway,
71144     defaultCheck: uiFieldCheck,
71145     email: uiFieldText,
71146     lanes: uiFieldLanes,
71147     localized: uiFieldLocalized,
71148     maxspeed: uiFieldMaxspeed,
71149     multiCombo: uiFieldCombo,
71150     networkCombo: uiFieldCombo,
71151     number: uiFieldText,
71152     onewayCheck: uiFieldCheck,
71153     radio: uiFieldRadio,
71154     restrictions: uiFieldRestrictions,
71155     semiCombo: uiFieldCombo,
71156     structureRadio: uiFieldRadio,
71157     tel: uiFieldText,
71158     text: uiFieldText,
71159     textarea: uiFieldTextarea,
71160     typeCombo: uiFieldCombo,
71161     url: uiFieldText,
71162     wikipedia: uiFieldWikipedia
71163 };
71164
71165 function uiField(context, presetField, entity, options) {
71166     options = lodash.extend({
71167         show: true,
71168         wrap: true,
71169         remove: true,
71170         revert: true,
71171         info: true
71172     }, options);
71173
71174     var dispatch$$1 = dispatch('change'),
71175         field = lodash.clone(presetField),
71176         state = '',
71177         tags = {};
71178
71179
71180     field.impl = uiFields[field.type](field, context)
71181         .on('change', function(t$$1, onInput) {
71182             dispatch$$1.call('change', field, t$$1, onInput);
71183         });
71184
71185     if (entity && field.impl.entity) {
71186         field.impl.entity(entity);
71187     }
71188
71189     field.keys = field.keys || [field.key];
71190
71191     field.show = options.show;
71192
71193
71194     function isModified() {
71195         if (!entity) return false;
71196         var original = context.graph().base().entities[entity.id];
71197         return lodash.some(field.keys, function(key) {
71198             return original ? tags[key] !== original.tags[key] : tags[key];
71199         });
71200     }
71201
71202
71203     function isPresent() {
71204         return lodash.some(field.keys, function(key) {
71205             return tags[key];
71206         });
71207     }
71208
71209
71210     function revert(d) {
71211         event.stopPropagation();
71212         event.preventDefault();
71213         if (!entity) return false;
71214
71215         var original = context.graph().base().entities[entity.id],
71216             t$$1 = {};
71217         d.keys.forEach(function(key) {
71218             t$$1[key] = original ? original.tags[key] : undefined;
71219         });
71220
71221         dispatch$$1.call('change', d, t$$1);
71222     }
71223
71224
71225     function remove(d) {
71226         event.stopPropagation();
71227         event.preventDefault();
71228
71229         var t$$1 = {};
71230         d.keys.forEach(function(key) {
71231             t$$1[key] = undefined;
71232         });
71233
71234         dispatch$$1.call('change', d, t$$1);
71235     }
71236
71237
71238     field.render = function(selection$$1) {
71239         var container = selection$$1.selectAll('.form-field')
71240             .data([field]);
71241
71242         // Enter
71243         var enter = container.enter()
71244             .append('div')
71245             .attr('class', function(d) { return 'form-field form-field-' + d.id; })
71246             .classed('nowrap', !options.wrap);
71247
71248         if (options.wrap) {
71249             var label = enter
71250                 .append('label')
71251                 .attr('class', 'form-label')
71252                 .attr('for', function(d) { return 'preset-input-' + d.id; })
71253                 .text(function(d) { return d.label(); });
71254
71255             var wrap = label
71256                 .append('div')
71257                 .attr('class', 'form-label-button-wrap');
71258
71259             if (options.remove) {
71260                 wrap
71261                     .append('button')
71262                     .attr('class', 'remove-icon')
71263                     .attr('tabindex', -1)
71264                     .call(svgIcon('#operation-delete'));
71265             }
71266
71267             if (options.revert) {
71268                 wrap
71269                     .append('button')
71270                     .attr('class', 'modified-icon')
71271                     .attr('tabindex', -1)
71272                     .call(
71273                         (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
71274                     );
71275             }
71276         }
71277
71278
71279         // Update
71280         container = container
71281             .merge(enter);
71282
71283         container.selectAll('.form-label-button-wrap .remove-icon')
71284             .on('click', remove);
71285
71286         container.selectAll('.form-label-button-wrap .modified-icon')
71287             .on('click', revert);
71288
71289         container
71290             .classed('modified', isModified())
71291             .classed('present', isPresent())
71292             .each(function(d) {
71293                 if (options.wrap && options.info) {
71294                     var referenceKey = d.key;
71295                     if (d.type === 'multiCombo') {   // lookup key without the trailing ':'
71296                         referenceKey = referenceKey.replace(/:$/, '');
71297                     }
71298                     var reference = uiTagReference(d.reference || { key: referenceKey }, context);
71299
71300                     if (state === 'hover') {
71301                         reference.showing(false);
71302                     }
71303                 }
71304
71305                 select(this)
71306                     .call(d.impl);
71307
71308                 if (options.wrap && options.info) {
71309                     select(this)
71310                         .call(reference.body)
71311                         .select('.form-label-button-wrap')
71312                         .call(reference.button);
71313                 }
71314
71315                 d.impl.tags(tags);
71316             });
71317     };
71318
71319
71320     field.state = function(_) {
71321         if (!arguments.length) return state;
71322         state = _;
71323         return field;
71324     };
71325
71326
71327     field.tags = function(_) {
71328         if (!arguments.length) return tags;
71329         tags = _;
71330         return field;
71331     };
71332
71333
71334     field.isShown = function() {
71335         return field.show || lodash.some(field.keys, function(key) { return !!tags[key]; });
71336     };
71337
71338
71339     field.focus = function() {
71340         field.impl.focus();
71341     };
71342
71343
71344     return utilRebind(field, dispatch$$1, 'on');
71345 }
71346
71347 function uiFormFields(context) {
71348     var fieldsArr;
71349
71350
71351     function formFields(selection$$1, klass) {
71352         render(selection$$1, klass);
71353     }
71354
71355
71356     function render(selection$$1, klass) {
71357
71358         var shown = fieldsArr.filter(function(field) { return field.isShown(); }),
71359             notShown = fieldsArr.filter(function(field) { return !field.isShown(); });
71360
71361         var container = selection$$1.selectAll('.form-fields-container')
71362             .data([0]);
71363
71364         container = container.enter()
71365             .append('div')
71366             .attr('class', 'form-fields-container ' + (klass || ''))
71367             .merge(container);
71368
71369
71370         var fields = container.selectAll('.wrap-form-field')
71371             .data(shown, function(d) { return d.id; });
71372
71373         fields.exit()
71374             .remove();
71375
71376         // Enter
71377         var enter = fields.enter()
71378             .append('div')
71379             .attr('class', function(d) { return 'wrap-form-field wrap-form-field-' + d.id; });
71380
71381         // Update
71382         fields = fields
71383             .merge(enter);
71384
71385         fields
71386             .order()
71387             .each(function(d) {
71388                 select(this)
71389                     .call(d.render);
71390             });
71391
71392
71393         notShown = notShown.map(function(field) {
71394             return {
71395                 title: field.label(),
71396                 value: field.label(),
71397                 field: field
71398             };
71399         });
71400
71401
71402         var more = selection$$1.selectAll('.more-fields')
71403             .data((notShown.length > 0) ? [0] : []);
71404
71405         more.exit()
71406             .remove();
71407
71408         more = more.enter()
71409             .append('div')
71410             .attr('class', 'more-fields')
71411             .append('label')
71412             .text(t('inspector.add_fields'))
71413             .merge(more);
71414
71415
71416         var input = more.selectAll('.value')
71417             .data([0]);
71418
71419         input.exit()
71420             .remove();
71421
71422         input = input.enter()
71423             .append('input')
71424             .attr('class', 'value')
71425             .attr('type', 'text')
71426             .call(utilNoAuto)
71427             .merge(input);
71428
71429         input
71430             .call(utilGetSetValue, '')
71431             .attr('placeholder', function() {
71432                 var placeholder = [];
71433                 for (var field in notShown) {
71434                     placeholder.push(notShown[field].title);
71435                 }
71436                 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
71437             })
71438             .call(d3combobox()
71439                 .container(context.container())
71440                 .data(notShown)
71441                 .minItems(1)
71442                 .on('accept', function (d) {
71443                     var field = d.field;
71444                     field.show = true;
71445                     render(selection$$1);
71446                     if (field.type !== 'semiCombo' && field.type !== 'multiCombo') {
71447                         field.focus();
71448                     }
71449                 })
71450             );
71451     }
71452
71453
71454     formFields.fieldsArr = function(_) {
71455         if (!arguments.length) return fieldsArr;
71456         fieldsArr = _;
71457         return formFields;
71458     };
71459
71460
71461     return formFields;
71462 }
71463
71464 function uiPresetEditor(context) {
71465     var dispatch$$1 = dispatch('change'),
71466         formFields = uiFormFields(context),
71467         expandedPreference = (context.storage('preset_fields.expanded') !== 'false'),
71468         state,
71469         fieldsArr,
71470         preset,
71471         tags,
71472         entityId;
71473
71474
71475     function presetEditor(selection$$1) {
71476         selection$$1.call(uiDisclosure()
71477             .title(t('inspector.all_fields'))
71478             .expanded(expandedPreference)
71479             .on('toggled', toggled)
71480             .content(render)
71481         );
71482
71483         function toggled(expanded) {
71484             expandedPreference = expanded;
71485             context.storage('preset_fields.expanded', expanded);
71486         }
71487     }
71488
71489
71490     function render(selection$$1) {
71491         if (!fieldsArr) {
71492             var entity = context.entity(entityId),
71493                 geometry = context.geometry(entityId),
71494                 presets = context.presets();
71495
71496             fieldsArr = [];
71497
71498             preset.fields.forEach(function(field) {
71499                 if (field.matchGeometry(geometry)) {
71500                     fieldsArr.push(
71501                         uiField(context, field, entity)
71502                     );
71503                 }
71504             });
71505
71506             if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
71507                 fieldsArr.push(
71508                     uiField(context, presets.field('restrictions'), entity)
71509                 );
71510             }
71511
71512             presets.universal().forEach(function(field) {
71513                 if (preset.fields.indexOf(field) === -1) {
71514                     fieldsArr.push(
71515                         uiField(context, field, entity, { show: false })
71516                     );
71517                 }
71518             });
71519
71520             fieldsArr.forEach(function(field) {
71521                 field
71522                     .on('change', function(t$$1, onInput) {
71523                         dispatch$$1.call('change', field, t$$1, onInput);
71524                     });
71525             });
71526         }
71527
71528         fieldsArr.forEach(function(field) {
71529             field
71530                 .state(state)
71531                 .tags(tags);
71532         });
71533
71534
71535         selection$$1
71536             .call(formFields.fieldsArr(fieldsArr), 'inspector-inner fillL3');
71537
71538
71539         selection$$1.selectAll('.wrap-form-field input')
71540             .on('keydown', function() {
71541                 // if user presses enter, and combobox is not active, accept edits..
71542                 if (event.keyCode === 13 && select('.combobox').empty()) {
71543                     context.enter(modeBrowse(context));
71544                 }
71545             });
71546     }
71547
71548
71549     presetEditor.preset = function(_) {
71550         if (!arguments.length) return preset;
71551         if (preset && preset.id === _.id) return presetEditor;
71552         preset = _;
71553         fieldsArr = null;
71554         return presetEditor;
71555     };
71556
71557
71558     presetEditor.state = function(_) {
71559         if (!arguments.length) return state;
71560         state = _;
71561         return presetEditor;
71562     };
71563
71564
71565     presetEditor.tags = function(_) {
71566         if (!arguments.length) return tags;
71567         tags = _;
71568         // Don't reset fieldsArr here.
71569         return presetEditor;
71570     };
71571
71572
71573     presetEditor.entityID = function(_) {
71574         if (!arguments.length) return entityId;
71575         if (entityId === _) return presetEditor;
71576         entityId = _;
71577         fieldsArr = null;
71578         return presetEditor;
71579     };
71580
71581
71582     return utilRebind(presetEditor, dispatch$$1, 'on');
71583 }
71584
71585 function uiEntityEditor(context) {
71586     var dispatch$$1 = dispatch('choose'),
71587         state = 'select',
71588         coalesceChanges = false,
71589         modified = false,
71590         base,
71591         entityId,
71592         activePreset,
71593         reference;
71594
71595     var presetEditor = uiPresetEditor(context)
71596         .on('change', changeTags);
71597     var rawTagEditor = uiRawTagEditor(context)
71598         .on('change', changeTags);
71599
71600
71601     function entityEditor(selection$$1) {
71602         var entity = context.entity(entityId),
71603             tags = lodash.clone(entity.tags);
71604
71605         // Header
71606         var header = selection$$1.selectAll('.header')
71607             .data([0]);
71608
71609         // Enter
71610         var enter = header.enter()
71611             .append('div')
71612             .attr('class', 'header fillL cf');
71613
71614         enter
71615             .append('button')
71616             .attr('class', 'fl preset-reset preset-choose')
71617             .call(svgIcon((textDirection === 'rtl') ? '#icon-forward' : '#icon-backward'));
71618
71619         enter
71620             .append('button')
71621             .attr('class', 'fr preset-close')
71622             .on('click', function() { context.enter(modeBrowse(context)); })
71623             .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
71624
71625         enter
71626             .append('h3')
71627             .text(t('inspector.edit'));
71628
71629         // Update
71630         header = header
71631             .merge(enter);
71632
71633         header.selectAll('.preset-reset')
71634             .on('click', function() {
71635                 dispatch$$1.call('choose', this, activePreset);
71636             });
71637
71638
71639         // Body
71640         var body = selection$$1.selectAll('.inspector-body')
71641             .data([0]);
71642
71643         // Enter
71644         enter = body.enter()
71645             .append('div')
71646             .attr('class', 'inspector-body');
71647
71648         enter
71649             .append('div')
71650             .attr('class', 'preset-list-item inspector-inner')
71651             .append('div')
71652             .attr('class', 'preset-list-button-wrap')
71653             .append('button')
71654             .attr('class', 'preset-list-button preset-reset')
71655             .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
71656             .append('div')
71657             .attr('class', 'label');
71658
71659         enter
71660             .append('div')
71661             .attr('class', 'inspector-border preset-editor');
71662
71663         enter
71664             .append('div')
71665             .attr('class', 'inspector-border raw-tag-editor inspector-inner');
71666
71667         enter
71668             .append('div')
71669             .attr('class', 'inspector-border raw-member-editor inspector-inner');
71670
71671         enter
71672             .append('div')
71673             .attr('class', 'raw-membership-editor inspector-inner');
71674
71675         enter
71676             .append('input')
71677             .attr('type', 'text')
71678             .attr('class', 'key-trap');
71679
71680
71681         // Update
71682         body = body
71683             .merge(enter);
71684
71685         body.selectAll('.preset-list-button-wrap')
71686             .call(reference.button);
71687
71688         body.selectAll('.preset-list-item')
71689             .call(reference.body);
71690
71691         body.selectAll('.preset-reset')
71692             .on('click', function() {
71693                 dispatch$$1.call('choose', this, activePreset);
71694             });
71695
71696         body.select('.preset-list-item button')
71697             .call(uiPresetIcon()
71698                 .geometry(context.geometry(entityId))
71699                 .preset(activePreset)
71700             );
71701
71702         body.select('.preset-list-item .label')
71703             .text(activePreset.name());
71704
71705         body.select('.preset-editor')
71706             .call(presetEditor
71707                 .preset(activePreset)
71708                 .entityID(entityId)
71709                 .tags(tags)
71710                 .state(state)
71711             );
71712
71713         body.select('.raw-tag-editor')
71714             .call(rawTagEditor
71715                 .preset(activePreset)
71716                 .entityID(entityId)
71717                 .tags(tags)
71718                 .state(state)
71719             );
71720
71721         if (entity.type === 'relation') {
71722             body.select('.raw-member-editor')
71723                 .style('display', 'block')
71724                 .call(uiRawMemberEditor(context)
71725                     .entityID(entityId)
71726                 );
71727         } else {
71728             body.select('.raw-member-editor')
71729                 .style('display', 'none');
71730         }
71731
71732         body.select('.raw-membership-editor')
71733             .call(uiRawMembershipEditor(context)
71734                 .entityID(entityId)
71735             );
71736
71737         body.select('.key-trap')
71738             .on('keydown.key-trap', function() {
71739                 // On tabbing, send focus back to the first field on the inspector-body
71740                 // (probably the `name` field) #4159
71741                 if (event.keyCode === 9 && !event.shiftKey) {
71742                     event.preventDefault();
71743                     body.select('input').node().focus();
71744                 }
71745             });
71746
71747         context.history()
71748             .on('change.entity-editor', historyChanged);
71749
71750
71751         function historyChanged() {
71752             if (state === 'hide') return;
71753
71754             var entity = context.hasEntity(entityId),
71755                 graph = context.graph();
71756             if (!entity) return;
71757
71758             entityEditor.preset(context.presets().match(entity, graph));
71759             entityEditor.modified(base !== graph);
71760             entityEditor(selection$$1);
71761         }
71762     }
71763
71764
71765     function clean(o) {
71766
71767         function cleanVal(k, v) {
71768             function keepSpaces(k) {
71769                 return k.match(/_hours|_times/) !== null;
71770             }
71771
71772             var blacklist = ['description', 'note', 'fixme'];
71773             if (lodash.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
71774
71775             var cleaned = v.split(';')
71776                 .map(function(s) { return s.trim(); })
71777                 .join(keepSpaces(k) ? '; ' : ';');
71778
71779             // The code below is not intended to validate websites and emails.
71780             // It is only intended to prevent obvious copy-paste errors. (#2323)
71781             // clean website- and email-like tags
71782             if (k.indexOf('website') !== -1 ||
71783                 k.indexOf('email') !== -1 ||
71784                 cleaned.indexOf('http') === 0) {
71785                 cleaned = cleaned
71786                     .replace(/[\u200B-\u200F\uFEFF]/g, '');  // strip LRM and other zero width chars
71787
71788             }
71789
71790             return cleaned;
71791         }
71792
71793         var out = {}, k, v;
71794         for (k in o) {
71795             if (k && (v = o[k]) !== undefined) {
71796                 out[k] = cleanVal(k, v);
71797             }
71798         }
71799         return out;
71800     }
71801
71802
71803     // Tag changes that fire on input can all get coalesced into a single
71804     // history operation when the user leaves the field.  #2342
71805     function changeTags(changed, onInput) {
71806         var entity = context.entity(entityId),
71807             annotation = t('operations.change_tags.annotation'),
71808             tags = lodash.clone(entity.tags);
71809
71810         lodash.forEach(changed, function(v, k) {
71811             if (v !== undefined || tags.hasOwnProperty(k)) {
71812                 tags[k] = v;
71813             }
71814         });
71815
71816         if (!onInput) {
71817             tags = clean(tags);
71818         }
71819
71820         if (!lodash.isEqual(entity.tags, tags)) {
71821             if (coalesceChanges) {
71822                 context.overwrite(actionChangeTags(entityId, tags), annotation);
71823             } else {
71824                 context.perform(actionChangeTags(entityId, tags), annotation);
71825                 coalesceChanges = !!onInput;
71826             }
71827         }
71828     }
71829
71830
71831     entityEditor.modified = function(_) {
71832         if (!arguments.length) return modified;
71833         modified = _;
71834         selectAll('button.preset-close use')
71835             .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
71836     };
71837
71838
71839     entityEditor.state = function(_) {
71840         if (!arguments.length) return state;
71841         state = _;
71842         return entityEditor;
71843     };
71844
71845
71846     entityEditor.entityID = function(_) {
71847         if (!arguments.length) return entityId;
71848         entityId = _;
71849         base = context.graph();
71850         entityEditor.preset(context.presets().match(context.entity(entityId), base));
71851         entityEditor.modified(false);
71852         coalesceChanges = false;
71853         return entityEditor;
71854     };
71855
71856
71857     entityEditor.preset = function(_) {
71858         if (!arguments.length) return activePreset;
71859         if (_ !== activePreset) {
71860             activePreset = _;
71861             reference = uiTagReference(activePreset.reference(context.geometry(entityId)), context)
71862                 .showing(false);
71863         }
71864         return entityEditor;
71865     };
71866
71867
71868     return utilRebind(entityEditor, dispatch$$1, 'on');
71869 }
71870
71871 function uiPresetList(context) {
71872     var dispatch$$1 = dispatch('choose'),
71873         id,
71874         currentPreset,
71875         autofocus = false;
71876
71877
71878     function presetList(selection$$1) {
71879         var entity = context.entity(id),
71880             geometry = context.geometry(id);
71881
71882         // Treat entities on addr:interpolation lines as points, not vertices (#3241)
71883         if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
71884             geometry = 'point';
71885         }
71886
71887         var presets = context.presets().matchGeometry(geometry);
71888
71889         selection$$1.html('');
71890
71891         var messagewrap = selection$$1
71892             .append('div')
71893             .attr('class', 'header fillL cf');
71894
71895         var message = messagewrap
71896             .append('h3')
71897             .text(t('inspector.choose'));
71898
71899         if (context.entity(id).isUsed(context.graph())) {
71900             messagewrap
71901                 .append('button')
71902                 .attr('class', 'preset-choose')
71903                 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
71904                 .call(svgIcon((textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'));
71905         } else {
71906             messagewrap
71907                 .append('button')
71908                 .attr('class', 'close')
71909                 .on('click', function() {
71910                     context.enter(modeBrowse(context));
71911                 })
71912                 .call(svgIcon('#icon-close'));
71913         }
71914
71915         function keydown() {
71916             // hack to let delete shortcut work when search is autofocused
71917             if (search.property('value').length === 0 &&
71918                 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
71919                  event.keyCode === d3keybinding.keyCodes['⌦'])) {
71920                 event.preventDefault();
71921                 event.stopPropagation();
71922                 operationDelete([id], context)();
71923             } else if (search.property('value').length === 0 &&
71924                 (event.ctrlKey || event.metaKey) &&
71925                 event.keyCode === d3keybinding.keyCodes.z) {
71926                 event.preventDefault();
71927                 event.stopPropagation();
71928                 context.undo();
71929             } else if (!event.ctrlKey && !event.metaKey) {
71930                 select(this).on('keydown', null);
71931             }
71932         }
71933
71934         function keypress() {
71935             // enter
71936             var value = search.property('value');
71937             if (event.keyCode === 13 && value.length) {
71938                 list.selectAll('.preset-list-item:first-child').datum().choose();
71939             }
71940         }
71941
71942         function inputevent() {
71943             var value = search.property('value');
71944             list.classed('filtered', value.length);
71945             if (value.length) {
71946                 var results = presets.search(value, geometry);
71947                 message.text(t('inspector.results', {
71948                     n: results.collection.length,
71949                     search: value
71950                 }));
71951                 list.call(drawList, results);
71952             } else {
71953                 list.call(drawList, context.presets().defaults(geometry, 36));
71954                 message.text(t('inspector.choose'));
71955             }
71956         }
71957
71958         var searchWrap = selection$$1
71959             .append('div')
71960             .attr('class', 'search-header');
71961
71962         var search = searchWrap
71963             .append('input')
71964             .attr('class', 'preset-search-input')
71965             .attr('placeholder', t('inspector.search'))
71966             .attr('type', 'search')
71967             .call(utilNoAuto)
71968             .on('keydown', keydown)
71969             .on('keypress', keypress)
71970             .on('input', inputevent);
71971
71972         searchWrap
71973             .call(svgIcon('#icon-search', 'pre-text'));
71974
71975         if (autofocus) {
71976             search.node().focus();
71977         }
71978
71979         var listWrap = selection$$1
71980             .append('div')
71981             .attr('class', 'inspector-body');
71982
71983         var list = listWrap
71984             .append('div')
71985             .attr('class', 'preset-list fillL cf')
71986             .call(drawList, context.presets().defaults(geometry, 36));
71987     }
71988
71989
71990     function drawList(list, presets) {
71991         var collection = presets.collection.map(function(preset) {
71992             return preset.members ? CategoryItem(preset) : PresetItem(preset);
71993         });
71994
71995         var items = list.selectAll('.preset-list-item')
71996             .data(collection, function(d) { return d.preset.id; });
71997
71998         items.order();
71999
72000         items.exit()
72001             .remove();
72002
72003         items.enter()
72004             .append('div')
72005             .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
72006             .classed('current', function(item) { return item.preset === currentPreset; })
72007             .each(function(item) { select(this).call(item); })
72008             .style('opacity', 0)
72009             .transition()
72010             .style('opacity', 1);
72011     }
72012
72013
72014     function CategoryItem(preset) {
72015         var box, sublist, shown = false;
72016
72017         function item(selection$$1) {
72018             var wrap = selection$$1.append('div')
72019                 .attr('class', 'preset-list-button-wrap category col12');
72020
72021             var button = wrap
72022                 .append('button')
72023                 .attr('class', 'preset-list-button')
72024                 .classed('expanded', false)
72025                 .call(uiPresetIcon()
72026                     .geometry(context.geometry(id))
72027                     .preset(preset))
72028                 .on('click', function() {
72029                     var isExpanded = select(this).classed('expanded');
72030                     var iconName = isExpanded ?
72031                         (textDirection === 'rtl' ? '#icon-backward' : '#icon-forward') : '#icon-down';
72032                     select(this)
72033                         .classed('expanded', !isExpanded);
72034                     select(this).selectAll('div.label svg.icon use')
72035                         .attr('href', iconName);
72036                     item.choose();
72037                 });
72038
72039             var label = button
72040                 .append('div')
72041                 .attr('class', 'label');
72042
72043             label
72044                 .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'))
72045                 .append('span')
72046                 .html(function() { return preset.name() + '&hellip;'; });
72047
72048             box = selection$$1.append('div')
72049                 .attr('class', 'subgrid col12')
72050                 .style('max-height', '0px')
72051                 .style('opacity', 0);
72052
72053             box.append('div')
72054                 .attr('class', 'arrow');
72055
72056             sublist = box.append('div')
72057                 .attr('class', 'preset-list fillL3 cf fl');
72058         }
72059
72060
72061         item.choose = function() {
72062             if (!box || !sublist) return;
72063
72064             if (shown) {
72065                 shown = false;
72066                 box.transition()
72067                     .duration(200)
72068                     .style('opacity', '0')
72069                     .style('max-height', '0px')
72070                     .style('padding-bottom', '0px');
72071             } else {
72072                 shown = true;
72073                 sublist.call(drawList, preset.members);
72074                 box.transition()
72075                     .duration(200)
72076                     .style('opacity', '1')
72077                     .style('max-height', 200 + preset.members.collection.length * 80 + 'px')
72078                     .style('padding-bottom', '20px');
72079             }
72080         };
72081
72082         item.preset = preset;
72083
72084         return item;
72085     }
72086
72087
72088     function PresetItem(preset) {
72089         function item(selection$$1) {
72090             var wrap = selection$$1.append('div')
72091                 .attr('class', 'preset-list-button-wrap col12');
72092
72093             wrap.append('button')
72094                 .attr('class', 'preset-list-button')
72095                 .call(uiPresetIcon()
72096                     .geometry(context.geometry(id))
72097                     .preset(preset))
72098                 .on('click', item.choose)
72099                 .append('div')
72100                 .attr('class', 'label')
72101                 .text(preset.name());
72102
72103             wrap.call(item.reference.button);
72104             selection$$1.call(item.reference.body);
72105         }
72106
72107         item.choose = function() {
72108             context.presets().choose(preset);
72109
72110             context.perform(
72111                 actionChangePreset(id, currentPreset, preset),
72112                 t('operations.change_tags.annotation')
72113             );
72114
72115             dispatch$$1.call('choose', this, preset);
72116         };
72117
72118         item.help = function() {
72119             event.stopPropagation();
72120             item.reference.toggle();
72121         };
72122
72123         item.preset = preset;
72124         item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
72125
72126         return item;
72127     }
72128
72129
72130     presetList.autofocus = function(_) {
72131         if (!arguments.length) return autofocus;
72132         autofocus = _;
72133         return presetList;
72134     };
72135
72136
72137     presetList.entityID = function(_) {
72138         if (!arguments.length) return id;
72139         id = _;
72140         presetList.preset(context.presets().match(context.entity(id), context.graph()));
72141         return presetList;
72142     };
72143
72144
72145     presetList.preset = function(_) {
72146         if (!arguments.length) return currentPreset;
72147         currentPreset = _;
72148         return presetList;
72149     };
72150
72151
72152     return utilRebind(presetList, dispatch$$1, 'on');
72153 }
72154
72155 function uiViewOnOSM(context) {
72156     var id;
72157
72158     function viewOnOSM(selection) {
72159         var entity = context.entity(id);
72160
72161         selection.style('display', entity.isNew() ? 'none' : null);
72162
72163         var link = selection.selectAll('.view-on-osm')
72164             .data([0]);
72165
72166         var enter = link.enter()
72167             .append('a')
72168             .attr('class', 'view-on-osm')
72169             .attr('target', '_blank')
72170             .call(svgIcon('#icon-out-link', 'inline'));
72171
72172         enter
72173             .append('span')
72174             .text(t('inspector.view_on_osm'));
72175
72176         link
72177             .merge(enter)
72178             .attr('href', context.connection().entityURL(entity));
72179     }
72180
72181
72182     viewOnOSM.entityID = function(_) {
72183         if (!arguments.length) return id;
72184         id = _;
72185         return viewOnOSM;
72186     };
72187
72188     return viewOnOSM;
72189 }
72190
72191 function uiInspector(context) {
72192     var presetList = uiPresetList(context),
72193         entityEditor = uiEntityEditor(context),
72194         state = 'select',
72195         entityID,
72196         newFeature = false;
72197
72198
72199     function inspector(selection$$1) {
72200         presetList
72201             .entityID(entityID)
72202             .autofocus(newFeature)
72203             .on('choose', setPreset);
72204
72205         entityEditor
72206             .state(state)
72207             .entityID(entityID)
72208             .on('choose', showList);
72209
72210         var wrap = selection$$1.selectAll('.panewrap')
72211             .data([0]);
72212
72213         var enter = wrap.enter()
72214             .append('div')
72215             .attr('class', 'panewrap');
72216
72217         enter
72218             .append('div')
72219             .attr('class', 'preset-list-pane pane');
72220
72221         enter
72222             .append('div')
72223             .attr('class', 'entity-editor-pane pane');
72224
72225         wrap = wrap.merge(enter);
72226         var presetPane = wrap.selectAll('.preset-list-pane');
72227         var editorPane = wrap.selectAll('.entity-editor-pane');
72228
72229         var graph = context.graph(),
72230             entity = context.entity(entityID),
72231             showEditor = state === 'hover' ||
72232                 entity.isUsed(graph) ||
72233                 entity.isHighwayIntersection(graph);
72234
72235         if (showEditor) {
72236             wrap.style('right', '0%');
72237             editorPane.call(entityEditor);
72238         } else {
72239             wrap.style('right', '-100%');
72240             presetPane.call(presetList);
72241         }
72242
72243         var footer = selection$$1.selectAll('.footer')
72244             .data([0]);
72245
72246         footer = footer.enter()
72247             .append('div')
72248             .attr('class', 'footer')
72249             .merge(footer);
72250
72251         footer
72252             .call(uiViewOnOSM(context).entityID(entityID));
72253
72254
72255         function showList(preset) {
72256             wrap.transition()
72257                 .styleTween('right', function() { return interpolateValue('0%', '-100%'); });
72258
72259             presetPane
72260                 .call(presetList.preset(preset).autofocus(true));
72261         }
72262
72263
72264         function setPreset(preset) {
72265             wrap.transition()
72266                 .styleTween('right', function() { return interpolateValue('-100%', '0%'); });
72267
72268             editorPane
72269                 .call(entityEditor.preset(preset));
72270         }
72271     }
72272
72273
72274     inspector.state = function(_) {
72275         if (!arguments.length) return state;
72276         state = _;
72277         entityEditor.state(state);
72278         return inspector;
72279     };
72280
72281
72282     inspector.entityID = function(_) {
72283         if (!arguments.length) return entityID;
72284         entityID = _;
72285         return inspector;
72286     };
72287
72288
72289     inspector.newFeature = function(_) {
72290         if (!arguments.length) return newFeature;
72291         newFeature = _;
72292         return inspector;
72293     };
72294
72295
72296     return inspector;
72297 }
72298
72299 function uiNotice(context) {
72300
72301     return function(selection) {
72302         var div = selection
72303             .append('div')
72304             .attr('class', 'notice');
72305
72306         var button = div
72307             .append('button')
72308             .attr('class', 'zoom-to notice')
72309             .on('click', function() { context.map().zoom(context.minEditableZoom()); });
72310
72311         button
72312             .call(svgIcon('#icon-plus', 'pre-text'))
72313             .append('span')
72314             .attr('class', 'label')
72315             .text(t('zoom_in_edit'));
72316
72317
72318         function disableTooHigh() {
72319             div.style('display', context.editable() ? 'none' : 'block');
72320         }
72321
72322         context.map()
72323             .on('move.notice', lodash.debounce(disableTooHigh, 500));
72324
72325         disableTooHigh();
72326     };
72327 }
72328
72329 function uiSidebar(context) {
72330     var inspector = uiInspector(context),
72331         current;
72332
72333
72334     function sidebar(selection) {
72335         var featureListWrap = selection
72336             .append('div')
72337             .attr('class', 'feature-list-pane')
72338             .call(uiFeatureList(context));
72339
72340         selection
72341             .call(uiNotice(context));
72342
72343         var inspectorWrap = selection
72344             .append('div')
72345             .attr('class', 'inspector-hidden inspector-wrap fr');
72346
72347
72348         function hover(id) {
72349             if (!current && context.hasEntity(id)) {
72350                 featureListWrap
72351                     .classed('inspector-hidden', true);
72352
72353                 inspectorWrap
72354                     .classed('inspector-hidden', false)
72355                     .classed('inspector-hover', true);
72356
72357                 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
72358                     inspector
72359                         .state('hover')
72360                         .entityID(id);
72361
72362                     inspectorWrap
72363                         .call(inspector);
72364                 }
72365
72366             } else if (!current) {
72367                 featureListWrap
72368                     .classed('inspector-hidden', false);
72369                 inspectorWrap
72370                     .classed('inspector-hidden', true);
72371                 inspector
72372                     .state('hide');
72373             }
72374         }
72375
72376
72377         sidebar.hover = lodash.throttle(hover, 200);
72378
72379
72380         sidebar.select = function(id, newFeature) {
72381             if (!current && id) {
72382                 featureListWrap
72383                     .classed('inspector-hidden', true);
72384
72385                 inspectorWrap
72386                     .classed('inspector-hidden', false)
72387                     .classed('inspector-hover', false);
72388
72389                 if (inspector.entityID() !== id || inspector.state() !== 'select') {
72390                     inspector
72391                         .state('select')
72392                         .entityID(id)
72393                         .newFeature(newFeature);
72394
72395                     inspectorWrap
72396                         .call(inspector);
72397                 }
72398
72399             } else if (!current) {
72400                 featureListWrap
72401                     .classed('inspector-hidden', false);
72402                 inspectorWrap
72403                     .classed('inspector-hidden', true);
72404                 inspector
72405                     .state('hide');
72406             }
72407         };
72408
72409
72410         sidebar.show = function(component) {
72411             featureListWrap
72412                 .classed('inspector-hidden', true);
72413             inspectorWrap
72414                 .classed('inspector-hidden', true);
72415
72416             if (current) current.remove();
72417             current = selection
72418                 .append('div')
72419                 .attr('class', 'sidebar-component')
72420                 .call(component);
72421         };
72422
72423
72424         sidebar.hide = function() {
72425             featureListWrap
72426                 .classed('inspector-hidden', false);
72427             inspectorWrap
72428                 .classed('inspector-hidden', true);
72429
72430             if (current) current.remove();
72431             current = null;
72432         };
72433     }
72434
72435
72436     sidebar.hover = function() {};
72437     sidebar.hover.cancel = function() {};
72438     sidebar.select = function() {};
72439     sidebar.show = function() {};
72440     sidebar.hide = function() {};
72441
72442     return sidebar;
72443 }
72444
72445 function uiSpinner(context) {
72446     var osm = context.connection();
72447
72448
72449     return function(selection) {
72450         var img = selection
72451             .append('img')
72452             .attr('src', context.imagePath('loader-black.gif'))
72453             .style('opacity', 0);
72454
72455         if (osm) {
72456             osm
72457                 .on('loading.spinner', function() {
72458                     img.transition()
72459                         .style('opacity', 1);
72460                 })
72461                 .on('loaded.spinner', function() {
72462                     img.transition()
72463                         .style('opacity', 0);
72464                 });
72465         }
72466     };
72467 }
72468
72469 function uiSplash(context) {
72470
72471     return function(selection) {
72472         if (context.storage('sawSplash'))
72473              return;
72474
72475         context.storage('sawSplash', true);
72476
72477         var modalSelection = uiModal(selection);
72478
72479         modalSelection.select('.modal')
72480             .attr('class', 'modal-splash modal col6');
72481
72482         var introModal = modalSelection.select('.content')
72483             .append('div')
72484             .attr('class', 'fillL');
72485
72486         introModal
72487             .append('div')
72488             .attr('class','modal-section cf')
72489             .append('h3').text(t('splash.welcome'));
72490
72491         introModal
72492             .append('div')
72493             .attr('class','modal-section')
72494             .append('p')
72495             .html(t('splash.text', {
72496                 version: context.version,
72497                 website: '<a href="http://ideditor.com/">ideditor.com</a>',
72498                 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
72499             }));
72500
72501         var buttonWrap = introModal
72502             .append('div')
72503             .attr('class', 'modal-actions cf');
72504
72505         var walkthrough = buttonWrap
72506             .append('button')
72507             .attr('class', 'walkthrough col6')
72508             .on('click', function() {
72509                 context.container().call(uiIntro(context));
72510                 modalSelection.close();
72511             });
72512
72513         walkthrough
72514             .append('svg')
72515             .attr('class', 'logo logo-walkthrough')
72516             .append('use')
72517             .attr('xlink:href', '#logo-walkthrough');
72518
72519         walkthrough
72520             .append('div')
72521             .text(t('splash.walkthrough'));
72522
72523         var startEditing = buttonWrap
72524             .append('button')
72525             .attr('class', 'start-editing col6')
72526             .on('click', modalSelection.close);
72527
72528         startEditing
72529             .append('svg')
72530             .attr('class', 'logo logo-features')
72531             .append('use')
72532             .attr('xlink:href', '#logo-features');
72533
72534         startEditing
72535             .append('div')
72536             .text(t('splash.start'));
72537
72538
72539         modalSelection.select('button.close')
72540             .attr('class','hide');
72541
72542     };
72543 }
72544
72545 function uiStatus(context) {
72546     var osm = context.connection();
72547
72548
72549     return function(selection$$1) {
72550         if (!osm) return;
72551
72552         function update() {
72553             osm.status(function(err, apiStatus) {
72554                 selection$$1.html('');
72555
72556                 if (err) {
72557                     if (apiStatus === 'rateLimited') {
72558                         selection$$1
72559                             .text(t('status.rateLimit'))
72560                             .append('a')
72561                             .attr('class', 'api-status-login')
72562                             .attr('target', '_blank')
72563                             .call(svgIcon('#icon-out-link', 'inline'))
72564                             .append('span')
72565                             .text(t('login'))
72566                             .on('click.login', function() {
72567                                 event.preventDefault();
72568                                 osm.authenticate();
72569                             });
72570                     } else {
72571                         // TODO: nice messages for different error types
72572                         selection$$1.text(t('status.error'));
72573                     }
72574
72575                 } else if (apiStatus === 'readonly') {
72576                     selection$$1.text(t('status.readonly'));
72577                 } else if (apiStatus === 'offline') {
72578                     selection$$1.text(t('status.offline'));
72579                 }
72580
72581                 selection$$1.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
72582             });
72583         }
72584
72585         osm.on('change', function() { update(selection$$1); });
72586
72587         window.setInterval(update, 90000);
72588         update(selection$$1);
72589     };
72590 }
72591
72592 function uiUndoRedo(context) {
72593     var commands = [{
72594         id: 'undo',
72595         cmd: uiCmd('⌘Z'),
72596         action: function() { if (!saving()) context.undo(); },
72597         annotation: function() { return context.history().undoAnnotation(); }
72598     }, {
72599         id: 'redo',
72600         cmd: uiCmd('⌘⇧Z'),
72601         action: function() { if (!saving()) context.redo(); },
72602         annotation: function() { return context.history().redoAnnotation(); }
72603     }];
72604
72605
72606     function saving() {
72607         return context.mode().id === 'save';
72608     }
72609
72610
72611     return function(selection$$1) {
72612         var tooltipBehavior = tooltip()
72613             .placement('bottom')
72614             .html(true)
72615             .title(function (d) {
72616                 return uiTooltipHtml(d.annotation() ?
72617                     t(d.id + '.tooltip', {action: d.annotation()}) :
72618                     t(d.id + '.nothing'), d.cmd);
72619             });
72620
72621         var buttons = selection$$1.selectAll('button')
72622             .data(commands)
72623             .enter()
72624             .append('button')
72625             .attr('class', function(d) { return 'col6 disabled ' + d.id + '-button'; })
72626             .on('click', function(d) { return d.action(); })
72627             .call(tooltipBehavior);
72628
72629         buttons.each(function(d) {
72630             var iconName = d.id;
72631             if (textDirection === 'rtl') {
72632                 if (iconName === 'undo') {
72633                     iconName = 'redo';
72634                 } else if (iconName === 'redo') {
72635                     iconName = 'undo';
72636                 }
72637             }
72638             select(this)
72639                 .call(svgIcon('#icon-' + iconName));
72640         });
72641
72642         var keybinding = d3keybinding('undo')
72643             .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
72644             .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
72645
72646         select(document)
72647             .call(keybinding);
72648
72649         context.history()
72650             .on('change.undo_redo', update);
72651
72652         context
72653             .on('enter.undo_redo', update);
72654
72655         function update() {
72656             buttons
72657                 .property('disabled', saving())
72658                 .classed('disabled', function(d) { return !d.annotation(); })
72659                 .each(function() {
72660                     var selection$$1 = select(this);
72661                     if (selection$$1.property('tooltipVisible')) {
72662                         selection$$1.call(tooltipBehavior.show);
72663                     }
72664                 });
72665         }
72666     };
72667 }
72668
72669 // these are module variables so they are preserved through a ui.restart()
72670 var sawVersion = null;
72671 var isNewVersion = false;
72672 var isNewUser = false;
72673
72674
72675 function uiVersion(context) {
72676
72677     var currVersion = context.version,
72678         matchedVersion = currVersion.match(/\d\.\d\.\d.*/);
72679
72680     if (sawVersion === null && matchedVersion !== null) {
72681         isNewVersion = (context.storage('sawVersion') !== currVersion);
72682         isNewUser = !context.storage('sawSplash');
72683         context.storage('sawVersion', currVersion);
72684         sawVersion = currVersion;
72685     }
72686
72687     return function(selection) {
72688         selection
72689             .append('a')
72690             .attr('target', '_blank')
72691             .attr('tabindex', -1)
72692             .attr('href', 'https://github.com/openstreetmap/iD')
72693             .text(currVersion);
72694
72695         // only show new version indicator to users that have used iD before
72696         if (isNewVersion && !isNewUser) {
72697             selection
72698                 .append('div')
72699                 .attr('class', 'badge')
72700                 .append('a')
72701                 .attr('target', '_blank')
72702                 .attr('tabindex', -1)
72703                 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CHANGELOG.md#whats-new')
72704                 .call(svgIcon('#gift-11'))
72705                 .call(tooltip()
72706                     .title(t('version.whats_new', { version: currVersion }))
72707                     .placement('top')
72708                 );
72709         }
72710     };
72711 }
72712
72713 function uiZoom(context) {
72714     var zooms = [{
72715         id: 'zoom-in',
72716         icon: 'plus',
72717         title: t('zoom.in'),
72718         action: context.zoomIn,
72719         key: '+'
72720     }, {
72721         id: 'zoom-out',
72722         icon: 'minus',
72723         title: t('zoom.out'),
72724         action: context.zoomOut,
72725         key: '-'
72726     }];
72727
72728
72729     function zoomIn() {
72730         event.preventDefault();
72731         context.zoomIn();
72732     }
72733
72734
72735     function zoomOut() {
72736         event.preventDefault();
72737         context.zoomOut();
72738     }
72739
72740
72741     function zoomInFurther() {
72742         event.preventDefault();
72743         context.zoomInFurther();
72744     }
72745
72746
72747     function zoomOutFurther() {
72748         event.preventDefault();
72749         context.zoomOutFurther();
72750     }
72751
72752
72753     return function(selection$$1) {
72754         var button = selection$$1.selectAll('button')
72755             .data(zooms)
72756             .enter()
72757             .append('button')
72758             .attr('tabindex', -1)
72759             .attr('class', function(d) { return d.id; })
72760             .on('click.editor', function(d) { d.action(); })
72761             .call(tooltip()
72762                 .placement((textDirection === 'rtl') ? 'right' : 'left')
72763                 .html(true)
72764                 .title(function(d) {
72765                     return uiTooltipHtml(d.title, d.key);
72766                 })
72767             );
72768
72769         button.each(function(d) {
72770             select(this)
72771                 .call(svgIcon('#icon-' + d.icon, 'light'));
72772         });
72773
72774         var keybinding = d3keybinding('zoom');
72775
72776        lodash.each(['plus', 'ffplus', '=', 'ffequals'], function(key) {
72777             keybinding.on([key], zoomIn);
72778             keybinding.on([uiCmd('⌘' + key)], zoomInFurther);
72779         });
72780
72781         lodash.each(['_', '-', 'ffminus', 'dash'], function(key) {
72782             keybinding.on([key], zoomOut);
72783             keybinding.on([uiCmd('⌘' + key)], zoomOutFurther);
72784         });
72785
72786         select(document)
72787             .call(keybinding);
72788     };
72789 }
72790
72791 function uiInit(context) {
72792     var uiInitCounter = 0;
72793
72794
72795     function render(container) {
72796         container
72797             .attr('dir', textDirection);
72798
72799         var map = context.map();
72800
72801         var hash = behaviorHash(context);
72802         hash();
72803
72804         if (!hash.hadHash) {
72805             map.centerZoom([0, 0], 2);
72806         }
72807
72808         container
72809             .append('svg')
72810             .attr('id', 'defs')
72811             .call(svgDefs(context));
72812
72813         container
72814             .append('div')
72815             .attr('id', 'sidebar')
72816             .attr('class', 'col4')
72817             .call(ui.sidebar);
72818
72819         var content = container
72820             .append('div')
72821             .attr('id', 'content')
72822             .attr('class', 'active');
72823
72824         var bar = content
72825             .append('div')
72826             .attr('id', 'bar')
72827             .attr('class', 'fillD');
72828
72829         content
72830             .append('div')
72831             .attr('id', 'map')
72832             .attr('dir', 'ltr')
72833             .call(map);
72834
72835         content
72836             .call(uiMapInMap(context))
72837             .call(uiInfo(context));
72838
72839         bar
72840             .append('div')
72841             .attr('class', 'spacer col4');
72842
72843         var limiter = bar.append('div')
72844             .attr('class', 'limiter');
72845
72846         limiter
72847             .append('div')
72848             .attr('class', 'button-wrap joined col3')
72849             .call(uiModes(context), limiter);
72850
72851         limiter
72852             .append('div')
72853             .attr('class', 'button-wrap joined col1')
72854             .call(uiUndoRedo(context));
72855
72856         limiter
72857             .append('div')
72858             .attr('class', 'button-wrap col1')
72859             .call(uiSave(context));
72860
72861         bar
72862             .append('div')
72863             .attr('class', 'full-screen')
72864             .call(uiFullScreen(context));
72865
72866         bar
72867             .append('div')
72868             .attr('class', 'spinner')
72869             .call(uiSpinner(context));
72870
72871
72872         var controls = bar
72873             .append('div')
72874             .attr('class', 'map-controls');
72875
72876         controls
72877             .append('div')
72878             .attr('class', 'map-control zoombuttons')
72879             .call(uiZoom(context));
72880
72881         controls
72882             .append('div')
72883             .attr('class', 'map-control geolocate-control')
72884             .call(uiGeolocate(context));
72885
72886         controls
72887             .append('div')
72888             .attr('class', 'map-control background-control')
72889             .call(uiBackground(context));
72890
72891         controls
72892             .append('div')
72893             .attr('class', 'map-control map-data-control')
72894             .call(uiMapData(context));
72895
72896         controls
72897             .append('div')
72898             .attr('class', 'map-control help-control')
72899             .call(uiHelp(context));
72900
72901
72902         var about = content
72903             .append('div')
72904             .attr('id', 'about');
72905
72906         about
72907             .append('div')
72908             .attr('id', 'attrib')
72909             .attr('dir', 'ltr')
72910             .call(uiAttribution(context));
72911
72912         about
72913             .append('div')
72914             .attr('class', 'api-status')
72915             .call(uiStatus(context));
72916
72917
72918         var footer = about
72919             .append('div')
72920             .attr('id', 'footer')
72921             .attr('class', 'fillD');
72922
72923         footer
72924             .append('div')
72925             .attr('id', 'flash-wrap')
72926             .attr('class', 'footer-hide');
72927
72928         var footerWrap = footer
72929             .append('div')
72930             .attr('id', 'footer-wrap')
72931             .attr('class', 'footer-show');
72932
72933         footerWrap
72934             .append('div')
72935             .attr('id', 'scale-block')
72936             .call(uiScale(context));
72937
72938         var aboutList = footerWrap
72939             .append('div')
72940             .attr('id', 'info-block')
72941             .append('ul')
72942             .attr('id', 'about-list');
72943
72944         if (!context.embed()) {
72945             aboutList
72946                 .call(uiAccount(context));
72947         }
72948
72949         aboutList
72950             .append('li')
72951             .attr('class', 'version')
72952             .call(uiVersion(context));
72953
72954         var issueLinks = aboutList
72955             .append('li');
72956
72957         issueLinks
72958             .append('a')
72959             .attr('target', '_blank')
72960             .attr('tabindex', -1)
72961             .attr('href', 'https://github.com/openstreetmap/iD/issues')
72962             .call(svgIcon('#icon-bug', 'light'))
72963             .call(tooltip().title(t('report_a_bug')).placement('top'));
72964
72965         issueLinks
72966             .append('a')
72967             .attr('target', '_blank')
72968             .attr('tabindex', -1)
72969             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
72970             .call(svgIcon('#icon-translate', 'light'))
72971             .call(tooltip().title(t('help_translate')).placement('top'));
72972
72973         aboutList
72974             .append('li')
72975             .attr('class', 'feature-warning')
72976             .attr('tabindex', -1)
72977             .call(uiFeatureInfo(context));
72978
72979         aboutList
72980             .append('li')
72981             .attr('class', 'user-list')
72982             .attr('tabindex', -1)
72983             .call(uiContributors(context));
72984
72985
72986         window.onbeforeunload = function() {
72987             return context.save();
72988         };
72989
72990         window.onunload = function() {
72991             context.history().unlock();
72992         };
72993
72994         var mapDimensions = map.dimensions();
72995
72996
72997         function onResize() {
72998             mapDimensions = utilGetDimensions(content, true);
72999             map.dimensions(mapDimensions);
73000         }
73001
73002         select(window)
73003             .on('resize.editor', onResize);
73004
73005         onResize();
73006
73007         function pan(d) {
73008             return function() {
73009                 event.preventDefault();
73010                 context.pan(d, 100);
73011             };
73012         }
73013
73014
73015         // pan amount
73016         var pa = 80;
73017
73018         var keybinding = d3keybinding('main')
73019             .on('⌫', function() { event.preventDefault(); })
73020             .on('←', pan([pa, 0]))
73021             .on('↑', pan([0, pa]))
73022             .on('→', pan([-pa, 0]))
73023             .on('↓', pan([0, -pa]))
73024             .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
73025             .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
73026             .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
73027             .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
73028
73029         select(document)
73030             .call(keybinding);
73031
73032         context.enter(modeBrowse(context));
73033
73034         if (!uiInitCounter++) {
73035             if (!hash.startWalkthrough) {
73036                 context.container()
73037                     .call(uiSplash(context))
73038                     .call(uiRestore(context));
73039             }
73040
73041             context.container()
73042                 .call(uiShortcuts(context));
73043         }
73044
73045         var osm = context.connection(),
73046             auth = uiLoading(context).message(t('loading_auth')).blocking(true);
73047
73048         if (osm && auth) {
73049             osm
73050                 .on('authLoading.ui', function() {
73051                     context.container()
73052                         .call(auth);
73053                 })
73054                 .on('authDone.ui', function() {
73055                     auth.close();
73056                 });
73057         }
73058
73059         uiInitCounter++;
73060
73061         if (hash.startWalkthrough) {
73062             hash.startWalkthrough = false;
73063             context.container().call(uiIntro(context));
73064         }
73065     }
73066
73067
73068     var renderCallback;
73069
73070     function ui(node, callback) {
73071         renderCallback = callback;
73072         var container = select(node);
73073         context.container(container);
73074         context.loadLocale(function(err) {
73075             if (!err) {
73076                 render(container);
73077             }
73078             if (callback) {
73079                 callback(err);
73080             }
73081         });
73082     }
73083
73084
73085     ui.restart = function(arg) {
73086         context.locale(arg);
73087         context.loadLocale(function(err) {
73088             if (!err) {
73089                 context.container().selectAll('*').remove();
73090                 render(context.container());
73091                 if (renderCallback) renderCallback();
73092             }
73093         });
73094     };
73095
73096
73097     ui.sidebar = uiSidebar(context);
73098
73099     return ui;
73100 }
73101
73102 function uiChangesetEditor(context) {
73103     var dispatch$$1 = dispatch('change'),
73104         formFields = uiFormFields(context),
73105         fieldsArr,
73106         tags,
73107         changesetId;
73108
73109
73110
73111     function changesetEditor(selection$$1) {
73112         render(selection$$1);
73113     }
73114
73115
73116     function render(selection$$1) {
73117         var initial = false;
73118
73119         if (!fieldsArr) {
73120             initial = true;
73121             var presets = context.presets();
73122
73123             fieldsArr = [
73124                 uiField(context, presets.field('comment'), null, { show: true, revert: false }),
73125                 uiField(context, presets.field('source'), null, { show: false, revert: false }),
73126                 uiField(context, presets.field('hashtags'), null, { show: false, revert: false }),
73127             ];
73128
73129             fieldsArr.forEach(function(field) {
73130                 field
73131                     .on('change', function(t$$1, onInput) {
73132                         dispatch$$1.call('change', field, t$$1, onInput);
73133                     });
73134             });
73135         }
73136
73137         fieldsArr.forEach(function(field) {
73138             field
73139                 .tags(tags);
73140         });
73141
73142
73143         selection$$1
73144             .call(formFields.fieldsArr(fieldsArr));
73145
73146
73147         if (initial) {
73148             var commentField = selection$$1.select('#preset-input-comment'),
73149                 commentNode = commentField.node();
73150
73151             if (commentNode) {
73152                 commentNode.focus();
73153                 commentNode.select();
73154             }
73155
73156             // trigger a 'blur' event so that comment field can be cleaned
73157             // and checked for hashtags, even if retrieved from localstorage
73158             utilTriggerEvent(commentField, 'blur');
73159
73160             var osm = context.connection();
73161             if (osm) {
73162                 osm.userChangesets(function (err, changesets) {
73163                     if (err) return;
73164
73165                     var comments = changesets.map(function(changeset) {
73166                         return {
73167                             title: changeset.tags.comment,
73168                             value: changeset.tags.comment
73169                         };
73170                     });
73171
73172                     commentField
73173                         .call(d3combobox()
73174                             .container(context.container())
73175                             .caseSensitive(true)
73176                             .data(lodash.uniqBy(comments, 'title'))
73177                         );
73178                 });
73179             }
73180         }
73181
73182         // Add warning if comment mentions Google
73183         var hasGoogle = tags.comment.match(/google/i);
73184         var commentWarning = selection$$1.select('.form-field-comment').selectAll('.comment-warning')
73185             .data(hasGoogle ? [0] : []);
73186
73187         commentWarning.exit()
73188             .transition()
73189             .duration(200)
73190             .style('opacity', 0)
73191             .remove();
73192
73193         var commentEnter = commentWarning.enter()
73194             .insert('div', '.tag-reference-body')
73195             .attr('class', 'field-warning comment-warning')
73196             .style('opacity', 0);
73197
73198         commentEnter
73199             .append('a')
73200             .attr('target', '_blank')
73201             .attr('tabindex', -1)
73202             .call(svgIcon('#icon-alert', 'inline'))
73203             .attr('href', t('commit.google_warning_link'))
73204             .append('span')
73205             .text(t('commit.google_warning'));
73206
73207         commentEnter
73208             .transition()
73209             .duration(200)
73210             .style('opacity', 1);
73211     }
73212
73213
73214     changesetEditor.tags = function(_) {
73215         if (!arguments.length) return tags;
73216         tags = _;
73217         // Don't reset fieldsArr here.
73218         return changesetEditor;
73219     };
73220
73221
73222     changesetEditor.changesetID = function(_) {
73223         if (!arguments.length) return changesetId;
73224         if (changesetId === _) return changesetEditor;
73225         changesetId = _;
73226         fieldsArr = null;
73227         return changesetEditor;
73228     };
73229
73230
73231     return utilRebind(changesetEditor, dispatch$$1, 'on');
73232 }
73233
73234 function uiCommitChanges(context) {
73235
73236     function commitChanges(selection$$1) {
73237
73238         var summary = context.history().difference().summary();
73239
73240         var container = selection$$1.selectAll('.modal-section.commit-section')
73241             .data([0]);
73242
73243         var containerEnter = container.enter()
73244             .append('div')
73245             .attr('class', 'commit-section modal-section fillL2');
73246
73247         containerEnter
73248             .append('h3')
73249             .text(t('commit.changes', { count: summary.length }));
73250
73251         containerEnter
73252             .append('ul')
73253             .attr('class', 'changeset-list');
73254
73255         container = containerEnter
73256             .merge(container);
73257
73258
73259         var items = container.select('ul').selectAll('li')
73260             .data(summary);
73261
73262         var itemsEnter = items.enter()
73263             .append('li')
73264             .attr('class', 'change-item');
73265
73266         itemsEnter
73267             .each(function(d) {
73268                 select(this)
73269                     .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
73270             });
73271
73272         itemsEnter
73273             .append('span')
73274             .attr('class', 'change-type')
73275             .text(function(d) { return t('commit.' + d.changeType) + ' '; });
73276
73277         itemsEnter
73278             .append('strong')
73279             .attr('class', 'entity-type')
73280             .text(function(d) {
73281                 var matched = context.presets().match(d.entity, d.graph);
73282                 return (matched && matched.name()) || utilDisplayType(d.entity.id);
73283             });
73284
73285         itemsEnter
73286             .append('span')
73287             .attr('class', 'entity-name')
73288             .text(function(d) {
73289                 var name = utilDisplayName(d.entity) || '',
73290                     string = '';
73291                 if (name !== '') {
73292                     string += ':';
73293                 }
73294                 return string += ' ' + name;
73295             });
73296
73297         itemsEnter
73298             .style('opacity', 0)
73299             .transition()
73300             .style('opacity', 1);
73301
73302         items = itemsEnter
73303             .merge(items);
73304
73305         items
73306             .on('mouseover', mouseover)
73307             .on('mouseout', mouseout)
73308             .on('click', zoomToEntity);
73309
73310
73311         function mouseover(d) {
73312             if (d.entity) {
73313                 context.surface().selectAll(
73314                     utilEntityOrMemberSelector([d.entity.id], context.graph())
73315                 ).classed('hover', true);
73316             }
73317         }
73318
73319
73320         function mouseout() {
73321             context.surface().selectAll('.hover')
73322                 .classed('hover', false);
73323         }
73324
73325
73326         function zoomToEntity(change) {
73327             var entity = change.entity;
73328             if (change.changeType !== 'deleted' &&
73329                 context.graph().entity(entity.id).geometry(context.graph()) !== 'vertex') {
73330                 context.map().zoomTo(entity);
73331                 context.surface().selectAll(utilEntityOrMemberSelector([entity.id], context.graph()))
73332                     .classed('hover', true);
73333             }
73334         }
73335     }
73336
73337
73338     return commitChanges;
73339 }
73340
73341 function uiCommitWarnings(context) {
73342
73343     function commitWarnings(selection) {
73344
73345         var changes = context.history().changes();
73346         var warnings = context.history().validate(changes);
73347
73348         var container = selection.selectAll('.warning-section')
73349             .data(warnings.length ? [0] : []);
73350
73351         container.exit()
73352             .remove();
73353
73354         var containerEnter = container.enter()
73355             .append('div')
73356             .attr('class', 'modal-section warning-section fillL2');
73357
73358         containerEnter
73359             .append('h3')
73360             .text(t('commit.warnings'));
73361
73362         containerEnter
73363             .append('ul')
73364             .attr('class', 'changeset-list');
73365
73366         container = containerEnter
73367             .merge(container);
73368
73369
73370         var items = container.select('ul').selectAll('li')
73371             .data(warnings);
73372
73373         items.exit()
73374             .remove();
73375
73376         var itemsEnter = items.enter()
73377             .append('li')
73378             .attr('class', 'warning-item');
73379
73380         itemsEnter
73381             .call(svgIcon('#icon-alert', 'pre-text'));
73382
73383         itemsEnter
73384             .append('strong')
73385             .text(function(d) { return d.message; });
73386
73387         itemsEnter.filter(function(d) { return d.tooltip; })
73388             .call(tooltip()
73389                 .title(function(d) { return d.tooltip; })
73390                 .placement('top')
73391             );
73392
73393         items = itemsEnter
73394             .merge(items);
73395
73396         items
73397             .on('mouseover', mouseover)
73398             .on('mouseout', mouseout)
73399             .on('click', warningClick);
73400
73401
73402         function mouseover(d) {
73403             if (d.entity) {
73404                 context.surface().selectAll(
73405                     utilEntityOrMemberSelector([d.entity.id], context.graph())
73406                 ).classed('hover', true);
73407             }
73408         }
73409
73410
73411         function mouseout() {
73412             context.surface().selectAll('.hover')
73413                 .classed('hover', false);
73414         }
73415
73416
73417         function warningClick(d) {
73418             if (d.entity) {
73419                 context.map().zoomTo(d.entity);
73420                 context.enter(modeSelect(context, [d.entity.id]));
73421             }
73422         }
73423
73424     }
73425
73426
73427     return commitWarnings;
73428 }
73429
73430 var changeset;
73431 var readOnlyTags = [
73432     /^changesets_count$/,
73433     /^created_by$/,
73434     /^ideditor:/,
73435     /^imagery_used$/,
73436     /^host$/,
73437     /^locale$/
73438 ];
73439
73440
73441 function uiCommit(context) {
73442     var dispatch$$1 = dispatch('cancel', 'save'),
73443         userDetails,
73444         _selection;
73445
73446     var changesetEditor = uiChangesetEditor(context)
73447         .on('change', changeTags);
73448     var rawTagEditor = uiRawTagEditor(context)
73449         .on('change', changeTags);
73450     var commitChanges = uiCommitChanges(context);
73451     var commitWarnings = uiCommitWarnings(context);
73452
73453
73454     function commit(selection$$1) {
73455         _selection = selection$$1;
73456
73457         var osm = context.connection();
73458         if (!osm) return;
73459
73460         var comment = context.storage('comment') || '',
73461             commentDate = +context.storage('commentDate') || 0,
73462             hashtags = context.storage('hashtags'),
73463             currDate = Date.now(),
73464             cutoff = 2 * 86400 * 1000;   // 2 days
73465
73466         // expire stored comment and hashtags after cutoff datetime - #3947
73467         if (commentDate > currDate || currDate - commentDate > cutoff) {
73468             comment = '';
73469             hashtags = undefined;
73470         }
73471
73472         var tags;
73473         if (!changeset) {
73474             var detected = utilDetect();
73475             tags = {
73476                 comment: comment,
73477                 created_by: ('iD ' + context.version).substr(0, 255),
73478                 imagery_used: context.history().imageryUsed().join(';').substr(0, 255),
73479                 host: detected.host.substr(0, 255),
73480                 locale: detected.locale.substr(0, 255)
73481             };
73482
73483             if (hashtags) {
73484                 tags.hashtags = hashtags;
73485             }
73486
73487             changeset = new osmChangeset({ tags: tags });
73488         }
73489
73490         tags = lodash.clone(changeset.tags);
73491
73492         var header = selection$$1.selectAll('.header')
73493             .data([0]);
73494
73495         header.enter()
73496             .append('div')
73497             .attr('class', 'header fillL')
73498             .append('h3')
73499             .text(t('commit.title'));
73500
73501         var body = selection$$1.selectAll('.body')
73502             .data([0]);
73503
73504         body = body.enter()
73505             .append('div')
73506             .attr('class', 'body')
73507             .merge(body);
73508
73509
73510         // Changeset Section
73511         var changesetSection = body.selectAll('.changeset-editor')
73512             .data([0]);
73513
73514         changesetSection = changesetSection.enter()
73515             .append('div')
73516             .attr('class', 'modal-section changeset-editor')
73517             .merge(changesetSection);
73518
73519         changesetSection
73520             .call(changesetEditor
73521                 .changesetID(changeset.id)
73522                 .tags(tags)
73523             );
73524
73525
73526         // Warnings
73527         body.call(commitWarnings);
73528
73529
73530         // Upload Explanation
73531         var saveSection = body.selectAll('.save-section')
73532             .data([0]);
73533
73534         saveSection = saveSection.enter()
73535             .append('div')
73536             .attr('class','modal-section save-section fillL cf')
73537             .merge(saveSection);
73538
73539         var prose = saveSection.selectAll('.commit-info')
73540             .data([0]);
73541
73542         prose = prose.enter()
73543             .append('p')
73544             .attr('class', 'commit-info')
73545             .text(t('commit.upload_explanation'))
73546             .merge(prose);
73547
73548         osm.userDetails(function(err, user) {
73549             if (err) return;
73550
73551             var userLink = select(document.createElement('div'));
73552
73553             userDetails = user;
73554
73555             if (user.image_url) {
73556                 userLink
73557                     .append('img')
73558                     .attr('src', user.image_url)
73559                     .attr('class', 'icon pre-text user-icon');
73560             }
73561
73562             userLink
73563                 .append('a')
73564                 .attr('class','user-info')
73565                 .text(user.display_name)
73566                 .attr('href', osm.userURL(user.display_name))
73567                 .attr('tabindex', -1)
73568                 .attr('target', '_blank');
73569
73570             prose
73571                 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
73572         });
73573
73574
73575         var requestReview = saveSection.selectAll('.request-review')
73576             .data([0]);
73577
73578         requestReview = requestReview.enter()
73579             .append('p')
73580             .attr('class', 'request-review')
73581             .text(t('commit.request_review'))
73582             .merge(requestReview);
73583
73584         var requestReviewField = requestReview.selectAll('input')
73585             .data([0]);
73586
73587         requestReviewField = requestReviewField.enter()
73588             .append('input')
73589             .attr('type', 'checkbox')
73590             .merge(requestReviewField);
73591
73592         requestReviewField
73593             .property('checked', isReviewRequested(changeset.tags))
73594             .on('change', toggleRequestReview);
73595
73596
73597         // Buttons
73598         var buttonSection = saveSection.selectAll('.buttons')
73599             .data([0]);
73600
73601         // enter
73602         var buttonEnter = buttonSection.enter()
73603             .append('div')
73604             .attr('class', 'buttons fillL cf');
73605
73606         buttonEnter
73607             .append('button')
73608             .attr('class', 'secondary-action col5 button cancel-button')
73609             .append('span')
73610             .attr('class', 'label')
73611             .text(t('commit.cancel'));
73612
73613         buttonEnter
73614             .append('button')
73615             .attr('class', 'action col5 button save-button')
73616             .append('span')
73617             .attr('class', 'label')
73618             .text(t('commit.save'));
73619
73620         // update
73621         buttonSection = buttonSection
73622             .merge(buttonEnter);
73623
73624         buttonSection.selectAll('.cancel-button')
73625             .on('click.cancel', function() {
73626                 dispatch$$1.call('cancel');
73627             });
73628
73629         buttonSection.selectAll('.save-button')
73630             .attr('disabled', function() {
73631                 var n = select('#preset-input-comment').node();
73632                 return (n && n.value.length) ? null : true;
73633             })
73634             .on('click.save', function() {
73635                 dispatch$$1.call('save', this, changeset);
73636             });
73637
73638
73639         // Raw Tag Editor
73640         var tagSection = body.selectAll('.tag-section.raw-tag-editor')
73641             .data([0]);
73642
73643         tagSection = tagSection.enter()
73644             .append('div')
73645             .attr('class', 'modal-section tag-section raw-tag-editor')
73646             .merge(tagSection);
73647
73648         var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
73649         tagSection
73650             .call(rawTagEditor
73651                 .expanded(expanded)
73652                 .readOnlyTags(readOnlyTags)
73653                 .tags(lodash.clone(changeset.tags))
73654             );
73655
73656
73657         // Change summary
73658         body.call(commitChanges);
73659
73660
73661         function toggleRequestReview() {
73662             var rr = requestReviewField.property('checked');
73663             updateChangeset({ review_requested: (rr ? 'yes' : undefined) });
73664
73665             var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
73666
73667             tagSection
73668                 .call(rawTagEditor
73669                     .expanded(expanded)
73670                     .readOnlyTags(readOnlyTags)
73671                     .tags(lodash.clone(changeset.tags))
73672                 );
73673         }
73674     }
73675
73676
73677     function changeTags(changed, onInput) {
73678         if (changed.hasOwnProperty('comment')) {
73679             if (changed.comment === undefined) {
73680                 changed.comment = '';
73681             }
73682             if (!onInput) {
73683                 context.storage('comment', changed.comment);
73684                 context.storage('commentDate', Date.now());
73685             }
73686         }
73687
73688         updateChangeset(changed, onInput);
73689
73690         if (_selection) {
73691             _selection.call(commit);
73692         }
73693     }
73694
73695
73696     function findHashtags(tags) {
73697         return lodash.unionBy(commentTags(), hashTags(), function (s) {
73698             return s.toLowerCase();
73699         });
73700
73701         // Extract hashtags from `comment`
73702         function commentTags() {
73703             return tags.comment.match(/#[^\s\#]+/g);
73704         }
73705
73706         // Extract and clean hashtags from `hashtags`
73707         function hashTags() {
73708             var t$$1 = tags.hashtags || '';
73709             return t$$1
73710                 .split(/[,;\s]+/)
73711                 .map(function (s) {
73712                     if (s[0] !== '#') { s = '#' + s; }    // prepend '#'
73713                     var matched = s.match(/#[^\s\#]+/g);  // match valid hashtags
73714                     return matched && matched[0];
73715                 }).filter(Boolean);                       // exclude falsey
73716         }
73717     }
73718
73719
73720     function isReviewRequested(tags) {
73721         var rr = tags.review_requested;
73722         if (rr === undefined) return false;
73723         rr = rr.trim().toLowerCase();
73724         return !(rr === '' || rr === 'no');
73725     }
73726
73727
73728     function updateChangeset(changed, onInput) {
73729         var tags = lodash.clone(changeset.tags);
73730
73731         lodash.forEach(changed, function(v, k) {
73732             k = k.trim().substr(0, 255);
73733             if (readOnlyTags.indexOf(k) !== -1) return;
73734
73735             if (k !== '' && v !== undefined) {
73736                 if (onInput) {
73737                     tags[k] = v;
73738                 } else {
73739                     tags[k] = v.trim().substr(0, 255);
73740                 }
73741             } else {
73742                 delete tags[k];
73743             }
73744         });
73745
73746         if (!onInput) {
73747             var arr = findHashtags(tags);
73748             if (arr.length) {
73749                 tags.hashtags = arr.join(';').substr(0, 255);
73750                 context.storage('hashtags', tags.hashtags);
73751             } else {
73752                 delete tags.hashtags;
73753                 context.storage('hashtags', null);
73754             }
73755         }
73756
73757         // always update userdetails, just in case user reauthenticates as someone else
73758         if (userDetails && userDetails.changesets_count !== undefined) {
73759             tags.changesets_count = String(userDetails.changesets_count);
73760
73761             // first 100 edits - new user
73762             if (parseInt(tags.changesets_count, 10) < 100) {
73763                 var s;
73764                 s = context.storage('walkthrough_completed');
73765                 if (s) {
73766                     tags['ideditor:walkthrough_completed'] = s;
73767                 }
73768
73769                 s = context.storage('walkthrough_progress');
73770                 if (s) {
73771                     tags['ideditor:walkthrough_progress'] = s;
73772                 }
73773
73774                 s = context.storage('walkthrough_started');
73775                 if (s) {
73776                     tags['ideditor:walkthrough_started'] = s;
73777                 }
73778             }
73779         } else {
73780             delete tags.changesets_count;
73781         }
73782
73783         if (!lodash.isEqual(changeset.tags, tags)) {
73784             changeset = changeset.update({ tags: tags });
73785         }
73786     }
73787
73788
73789     commit.reset = function() {
73790         changeset = null;
73791     };
73792
73793
73794     return utilRebind(commit, dispatch$$1, 'on');
73795 }
73796
73797 function uiConfirm(selection) {
73798     var modalSelection = uiModal(selection);
73799
73800     modalSelection.select('.modal')
73801         .classed('modal-alert', true);
73802
73803     var section = modalSelection.select('.content');
73804
73805     section.append('div')
73806         .attr('class', 'modal-section header');
73807
73808     section.append('div')
73809         .attr('class', 'modal-section message-text');
73810
73811     var buttons = section.append('div')
73812         .attr('class', 'modal-section buttons cf');
73813
73814
73815     modalSelection.okButton = function() {
73816         buttons
73817             .append('button')
73818             .attr('class', 'action col4')
73819             .on('click.confirm', function() {
73820                 modalSelection.remove();
73821             })
73822             .text(t('confirm.okay'));
73823
73824         return modalSelection;
73825     };
73826
73827
73828     return modalSelection;
73829 }
73830
73831 function uiConflicts(context) {
73832     var dispatch$$1 = dispatch('download', 'cancel', 'save'),
73833         list;
73834
73835
73836     function conflicts(selection$$1) {
73837         var header = selection$$1
73838             .append('div')
73839             .attr('class', 'header fillL');
73840
73841         header
73842             .append('button')
73843             .attr('class', 'fr')
73844             .on('click', function() { dispatch$$1.call('cancel'); })
73845             .call(svgIcon('#icon-close'));
73846
73847         header
73848             .append('h3')
73849             .text(t('save.conflict.header'));
73850
73851         var body = selection$$1
73852             .append('div')
73853             .attr('class', 'body fillL');
73854
73855         body
73856             .append('div')
73857             .attr('class', 'conflicts-help')
73858             .text(t('save.conflict.help'))
73859             .append('a')
73860             .attr('class', 'conflicts-download')
73861             .text(t('save.conflict.download_changes'))
73862             .on('click.download', function() { dispatch$$1.call('download'); });
73863
73864         body
73865             .append('div')
73866             .attr('class', 'conflict-container fillL3')
73867             .call(showConflict, 0);
73868
73869         body
73870             .append('div')
73871             .attr('class', 'conflicts-done')
73872             .attr('opacity', 0)
73873             .style('display', 'none')
73874             .text(t('save.conflict.done'));
73875
73876         var buttons = body
73877             .append('div')
73878             .attr('class','buttons col12 joined conflicts-buttons');
73879
73880         buttons
73881             .append('button')
73882             .attr('disabled', list.length > 1)
73883             .attr('class', 'action conflicts-button col6')
73884             .text(t('save.title'))
73885             .on('click.try_again', function() { dispatch$$1.call('save'); });
73886
73887         buttons
73888             .append('button')
73889             .attr('class', 'secondary-action conflicts-button col6')
73890             .text(t('confirm.cancel'))
73891             .on('click.cancel', function() { dispatch$$1.call('cancel'); });
73892     }
73893
73894
73895     function showConflict(selection$$1, index) {
73896         if (index < 0 || index >= list.length) return;
73897
73898         var parent = select(selection$$1.node().parentNode);
73899
73900         // enable save button if this is the last conflict being reviewed..
73901         if (index === list.length - 1) {
73902             window.setTimeout(function() {
73903                 parent.select('.conflicts-button')
73904                     .attr('disabled', null);
73905
73906                 parent.select('.conflicts-done')
73907                     .transition()
73908                     .attr('opacity', 1)
73909                     .style('display', 'block');
73910             }, 250);
73911         }
73912
73913         var item = selection$$1
73914             .selectAll('.conflict')
73915             .data([list[index]]);
73916
73917         var enter = item.enter()
73918             .append('div')
73919             .attr('class', 'conflict');
73920
73921         enter
73922             .append('h4')
73923             .attr('class', 'conflict-count')
73924             .text(t('save.conflict.count', { num: index + 1, total: list.length }));
73925
73926         enter
73927             .append('a')
73928             .attr('class', 'conflict-description')
73929             .attr('href', '#')
73930             .text(function(d) { return d.name; })
73931             .on('click', function(d) {
73932                 zoomToEntity(d.id);
73933                 event.preventDefault();
73934             });
73935
73936         var details = enter
73937             .append('div')
73938             .attr('class', 'conflict-detail-container');
73939
73940         details
73941             .append('ul')
73942             .attr('class', 'conflict-detail-list')
73943             .selectAll('li')
73944             .data(function(d) { return d.details || []; })
73945             .enter()
73946             .append('li')
73947             .attr('class', 'conflict-detail-item')
73948             .html(function(d) { return d; });
73949
73950         details
73951             .append('div')
73952             .attr('class', 'conflict-choices')
73953             .call(addChoices);
73954
73955         details
73956             .append('div')
73957             .attr('class', 'conflict-nav-buttons joined cf')
73958             .selectAll('button')
73959             .data(['previous', 'next'])
73960             .enter()
73961             .append('button')
73962             .text(function(d) { return t('save.conflict.' + d); })
73963             .attr('class', 'conflict-nav-button action col6')
73964             .attr('disabled', function(d, i) {
73965                 return (i === 0 && index === 0) ||
73966                     (i === 1 && index === list.length - 1) || null;
73967             })
73968             .on('click', function(d, i) {
73969                 var container = parent.select('.conflict-container'),
73970                 sign = (i === 0 ? -1 : 1);
73971
73972                 container
73973                     .selectAll('.conflict')
73974                     .remove();
73975
73976                 container
73977                     .call(showConflict, index + sign);
73978
73979                 event.preventDefault();
73980             });
73981
73982         item.exit()
73983             .remove();
73984     }
73985
73986
73987     function addChoices(selection$$1) {
73988         var choices = selection$$1
73989             .append('ul')
73990             .attr('class', 'layer-list')
73991             .selectAll('li')
73992             .data(function(d) { return d.choices || []; });
73993
73994         var enter = choices.enter()
73995             .append('li')
73996             .attr('class', 'layer');
73997
73998         var label = enter
73999             .append('label');
74000
74001         label
74002             .append('input')
74003             .attr('type', 'radio')
74004             .attr('name', function(d) { return d.id; })
74005             .on('change', function(d, i) {
74006                 var ul = this.parentNode.parentNode.parentNode;
74007                 ul.__data__.chosen = i;
74008                 choose(ul, d);
74009             });
74010
74011         label
74012             .append('span')
74013             .text(function(d) { return d.text; });
74014
74015         choices
74016             .each(function(d, i) {
74017                 var ul = this.parentNode;
74018                 if (ul.__data__.chosen === i) choose(ul, d);
74019             });
74020     }
74021
74022
74023     function choose(ul, datum) {
74024         if (event) event.preventDefault();
74025
74026         select(ul)
74027             .selectAll('li')
74028             .classed('active', function(d) { return d === datum; })
74029             .selectAll('input')
74030             .property('checked', function(d) { return d === datum; });
74031
74032         var extent$$1 = geoExtent$$1(),
74033             entity;
74034
74035         entity = context.graph().hasEntity(datum.id);
74036         if (entity) extent$$1._extend(entity.extent(context.graph()));
74037
74038         datum.action();
74039
74040         entity = context.graph().hasEntity(datum.id);
74041         if (entity) extent$$1._extend(entity.extent(context.graph()));
74042
74043         zoomToEntity(datum.id, extent$$1);
74044     }
74045
74046
74047     function zoomToEntity(id, extent$$1) {
74048         context.surface().selectAll('.hover')
74049             .classed('hover', false);
74050
74051         var entity = context.graph().hasEntity(id);
74052         if (entity) {
74053             if (extent$$1) {
74054                 context.map().trimmedExtent(extent$$1);
74055             } else {
74056                 context.map().zoomTo(entity);
74057             }
74058             context.surface().selectAll(
74059                 utilEntityOrMemberSelector([entity.id], context.graph()))
74060                 .classed('hover', true);
74061         }
74062     }
74063
74064
74065     // The conflict list should be an array of objects like:
74066     // {
74067     //     id: id,
74068     //     name: entityName(local),
74069     //     details: merge.conflicts(),
74070     //     chosen: 1,
74071     //     choices: [
74072     //         choice(id, keepMine, forceLocal),
74073     //         choice(id, keepTheirs, forceRemote)
74074     //     ]
74075     // }
74076     conflicts.list = function(_) {
74077         if (!arguments.length) return list;
74078         list = _;
74079         return conflicts;
74080     };
74081
74082
74083     return utilRebind(conflicts, dispatch$$1, 'on');
74084 }
74085
74086 function uiEditMenu(context, operations) {
74087     var menu,
74088         center = [0, 0],
74089         offset = [0, 0],
74090         tooltip;
74091
74092     var p = 8,               // top padding
74093         m = 4,               // top margin
74094         h = 15,              // height of icon
74095         vpBottomMargin = 45, // viewport bottom margin
74096         vpSideMargin = 35,   // viewport side margin
74097         buttonWidth = 44,
74098         buttonHeight = (2 * p + h),
74099         menuWidth = buttonWidth,
74100         menuHeight = (2 * m) + operations.length * buttonHeight,
74101         menuSideMargin = 10,
74102         tooltipWidth = 200,
74103         tooltipHeight = 200;  // a reasonable guess, real height depends on tooltip contents
74104
74105
74106     var editMenu = function (selection$$1) {
74107         if (!operations.length) return;
74108
74109         selection$$1.node().parentNode.focus();
74110
74111         var isRTL = textDirection === 'rtl',
74112             viewport = context.surfaceRect();
74113
74114         if (!isRTL && (center[0] + menuSideMargin + menuWidth) > (viewport.width - vpSideMargin)) {
74115             // menu is going left-to-right and near right viewport edge, go left instead
74116             isRTL = true;
74117         } else if (isRTL && (center[0] - menuSideMargin - menuWidth) < vpSideMargin) {
74118             // menu is going right-to-left and near left viewport edge, go right instead
74119             isRTL = false;
74120         }
74121
74122         offset[0] = (isRTL ? -1 * (menuSideMargin + menuWidth) : menuSideMargin);
74123
74124         if (center[1] + menuHeight > (viewport.height - vpBottomMargin)) {
74125             // menu is near bottom viewport edge, shift upwards
74126             offset[1] = -1 * (center[1] + menuHeight - viewport.height + vpBottomMargin);
74127         }
74128
74129         var origin = [ center[0] + offset[0], center[1] + offset[1] ];
74130
74131         menu = selection$$1
74132             .append('g')
74133             .attr('class', 'edit-menu')
74134             .attr('transform', 'translate(' + origin + ')')
74135             .attr('opacity', 0);
74136
74137         menu
74138             .transition()
74139             .attr('opacity', 1);
74140
74141         menu
74142             .append('rect')
74143             .attr('class', 'edit-menu-background')
74144             .attr('x', 4)
74145             .attr('rx', 4)
74146             .attr('ry', 4)
74147             .attr('width', menuWidth)
74148             .attr('height', menuHeight)
74149             .attr('stroke-linecap', 'round');
74150
74151
74152         var button = menu.selectAll('.edit-menu-item')
74153             .data(operations)
74154             .enter()
74155             .append('g')
74156             .attr('class', function (d) { return 'edit-menu-item edit-menu-item-' + d.id; })
74157             .classed('disabled', function (d) { return d.disabled(); })
74158             .attr('transform', function (d, i) {
74159                 return 'translate(' + geoRoundCoords([
74160                     0,
74161                     m + i * buttonHeight
74162                 ]).join(',') + ')';
74163             });
74164
74165         button
74166             .append('rect')
74167             .attr('x', 4)
74168             .attr('width', buttonWidth)
74169             .attr('height', buttonHeight)
74170             .on('click', click)
74171             .on('mousedown', mousedown)
74172             .on('mouseover', mouseover)
74173             .on('mouseout', mouseout);
74174
74175         button
74176             .append('use')
74177             .attr('width', '20')
74178             .attr('height', '20')
74179             .attr('transform', function () {
74180                 return 'translate(' + [2 * p, 5] + ')';
74181             })
74182             .attr('xlink:href', function (d) { return '#operation-' + d.id; });
74183
74184         tooltip = select(document.body)
74185             .append('div')
74186             .attr('class', 'tooltip-inner edit-menu-tooltip');
74187
74188
74189         function click(operation) {
74190             event.stopPropagation();
74191             if (operation.disabled()) return;
74192             operation();
74193             editMenu.close();
74194         }
74195
74196         function mousedown() {
74197             event.stopPropagation();  // https://github.com/openstreetmap/iD/issues/1869
74198         }
74199
74200         function mouseover(d, i) {
74201             var tipX, tipY;
74202
74203             if (!isRTL) {
74204                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
74205             } else {
74206                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
74207             }
74208
74209             if (tipX + tooltipWidth > viewport.right) {
74210                 // tip is going left-to-right and near right viewport edge, go left instead
74211                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
74212             } else if (tipX < viewport.left) {
74213                 // tip is going right-to-left and near left viewport edge, go right instead
74214                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
74215             }
74216
74217             tipY = viewport.top + origin[1] + (i * buttonHeight);
74218             if (tipY + tooltipHeight > viewport.bottom) {
74219                 // tip is near bottom viewport edge, shift upwards
74220                 tipY -= tipY + tooltipHeight - viewport.bottom;
74221             }
74222
74223             tooltip
74224                 .style('left', tipX + 'px')
74225                 .style('top', tipY + 'px')
74226                 .style('display', 'block')
74227                 .html(uiTooltipHtml(d.tooltip(), d.keys[0], d.title));
74228         }
74229
74230         function mouseout() {
74231             tooltip.style('display', 'none');
74232         }
74233     };
74234
74235
74236     editMenu.close = function () {
74237         if (menu) {
74238             menu
74239                 .style('pointer-events', 'none')
74240                 .transition()
74241                 .attr('opacity', 0)
74242                 .remove();
74243         }
74244
74245         if (tooltip) {
74246             tooltip.remove();
74247         }
74248     };
74249
74250
74251     editMenu.center = function (_) {
74252         if (!arguments.length) return center;
74253         center = _;
74254         return editMenu;
74255     };
74256
74257
74258     return editMenu;
74259 }
74260
74261 var timer$1;
74262
74263 function uiFlash(showDuration) {
74264     showDuration = showDuration || 1500;
74265
74266     if (timer$1) {
74267         timer$1.stop();
74268     }
74269
74270     select('#footer-wrap')
74271         .attr('class', 'footer-hide');
74272     select('#flash-wrap')
74273         .attr('class', 'footer-show');
74274
74275     var content = select('#flash-wrap').selectAll('.content')
74276         .data([0]);
74277
74278     content = content.enter()
74279         .append('div')
74280         .attr('class', 'content')
74281         .merge(content);
74282
74283     timer$1 = timeout$1(function() {
74284         timer$1 = null;
74285         select('#footer-wrap')
74286             .attr('class', 'footer-show');
74287         select('#flash-wrap')
74288             .attr('class', 'footer-hide');
74289     }, showDuration);
74290
74291
74292     return content;
74293 }
74294
74295 function uiLasso(context) {
74296     var group, polygon;
74297
74298     lasso.coordinates = [];
74299
74300     function lasso(selection$$1) {
74301         context.container()
74302             .classed('lasso', true);
74303
74304         group = selection$$1
74305             .append('g')
74306             .attr('class', 'lasso hide');
74307
74308         polygon = group
74309             .append('path')
74310             .attr('class', 'lasso-path');
74311
74312         group
74313             .call(uiToggle(true));
74314     }
74315
74316
74317     function draw() {
74318         if (polygon) {
74319             polygon.data([lasso.coordinates])
74320                 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
74321         }
74322     }
74323
74324
74325     lasso.extent = function () {
74326         return lasso.coordinates.reduce(function(extent$$1, point) {
74327             return extent$$1.extend(geoExtent$$1(point));
74328         }, geoExtent$$1());
74329     };
74330
74331
74332     lasso.p = function(_) {
74333         if (!arguments.length) return lasso;
74334         lasso.coordinates.push(_);
74335         draw();
74336         return lasso;
74337     };
74338
74339
74340     lasso.close = function() {
74341         if (group) {
74342             group.call(uiToggle(false, function() {
74343                 select(this).remove();
74344             }));
74345         }
74346         context.container().classed('lasso', false);
74347     };
74348
74349
74350     return lasso;
74351 }
74352
74353 function uiRadialMenu(context, operations) {
74354     var menu,
74355         center = [0, 0],
74356         tooltip;
74357
74358
74359     var radialMenu = function(selection$$1) {
74360         if (!operations.length) return;
74361
74362         selection$$1.node().parentNode.focus();
74363
74364         function click(operation) {
74365             event.stopPropagation();
74366             if (operation.disabled()) return;
74367             operation();
74368             radialMenu.close();
74369         }
74370
74371         menu = selection$$1
74372             .append('g')
74373             .attr('class', 'radial-menu')
74374             .attr('transform', 'translate(' + center + ')')
74375             .attr('opacity', 0);
74376
74377         menu
74378             .transition()
74379             .attr('opacity', 1);
74380
74381         var r = 50,
74382             a = Math.PI / 4,
74383             a0 = -Math.PI / 4,
74384             a1 = a0 + (operations.length - 1) * a;
74385
74386         menu
74387             .append('path')
74388             .attr('class', 'radial-menu-background')
74389             .attr('d', 'M' + r * Math.sin(a0) + ',' +
74390                              r * Math.cos(a0) +
74391                       ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
74392                              (r * Math.sin(a1) + 1e-3) + ',' +
74393                              (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
74394             .attr('stroke-width', 50)
74395             .attr('stroke-linecap', 'round');
74396
74397         var button = menu.selectAll()
74398             .data(operations)
74399             .enter()
74400             .append('g')
74401             .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
74402             .classed('disabled', function(d) { return d.disabled(); })
74403             .attr('transform', function(d, i) {
74404                 return 'translate(' + geoRoundCoords([
74405                         r * Math.sin(a0 + i * a),
74406                         r * Math.cos(a0 + i * a)]).join(',') + ')';
74407             });
74408
74409         button
74410             .append('circle')
74411             .attr('r', 15)
74412             .on('click', click)
74413             .on('mousedown', mousedown)
74414             .on('mouseover', mouseover)
74415             .on('mouseout', mouseout);
74416
74417         button
74418             .append('use')
74419             .attr('transform', 'translate(-10,-10)')
74420             .attr('width', '20')
74421             .attr('height', '20')
74422             .attr('xlink:href', function(d) { return '#operation-' + d.id; });
74423
74424         tooltip = select(document.body)
74425             .append('div')
74426             .attr('class', 'tooltip-inner radial-menu-tooltip');
74427
74428         function mousedown() {
74429             event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
74430         }
74431
74432         function mouseover(d, i) {
74433             var rect = context.surfaceRect(),
74434                 angle = a0 + i * a,
74435                 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
74436                 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
74437                 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
74438                 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
74439
74440             tooltip
74441                 .style('top', null)
74442                 .style('left', null)
74443                 .style('bottom', null)
74444                 .style('right', null)
74445                 .style('display', 'block')
74446                 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
74447
74448             if (i === 0) {
74449                 tooltip
74450                     .style('right', right)
74451                     .style('top', top);
74452             } else if (i >= 4) {
74453                 tooltip
74454                     .style('left', left)
74455                     .style('bottom', bottom);
74456             } else {
74457                 tooltip
74458                     .style('left', left)
74459                     .style('top', top);
74460             }
74461         }
74462
74463         function mouseout() {
74464             tooltip.style('display', 'none');
74465         }
74466     };
74467
74468
74469     radialMenu.close = function() {
74470         if (menu) {
74471             menu
74472                 .style('pointer-events', 'none')
74473                 .transition()
74474                 .attr('opacity', 0)
74475                 .remove();
74476         }
74477
74478         if (tooltip) {
74479             tooltip.remove();
74480         }
74481     };
74482
74483
74484     radialMenu.center = function(_) {
74485         if (!arguments.length) return center;
74486         center = _;
74487         return radialMenu;
74488     };
74489
74490
74491     return radialMenu;
74492 }
74493
74494 function uiSelectionList(context, selectedIDs) {
74495
74496     function selectEntity(entity) {
74497         context.enter(modeSelect(context, [entity.id]));
74498     }
74499
74500
74501     function deselectEntity(entity) {
74502         event.stopPropagation();
74503         var index = selectedIDs.indexOf(entity.id);
74504         if (index > -1) {
74505             selectedIDs.splice(index, 1);
74506         }
74507         context.enter(modeSelect(context, selectedIDs));
74508     }
74509
74510
74511     function selectionList(selection$$1) {
74512         selection$$1.classed('selection-list-pane', true);
74513
74514         var header = selection$$1
74515             .append('div')
74516             .attr('class', 'header fillL cf');
74517
74518         header
74519             .append('h3')
74520             .text(t('inspector.multiselect'));
74521
74522         var listWrap = selection$$1
74523             .append('div')
74524             .attr('class', 'inspector-body');
74525
74526         var list = listWrap
74527             .append('div')
74528             .attr('class', 'feature-list cf');
74529
74530         context.history().on('change.selection-list', drawList);
74531         drawList();
74532
74533
74534         function drawList() {
74535             var entities = selectedIDs
74536                 .map(function(id) { return context.hasEntity(id); })
74537                 .filter(function(entity) { return entity; });
74538
74539             var items = list.selectAll('.feature-list-item')
74540                 .data(entities, osmEntity$$1.key);
74541
74542             items.exit()
74543                 .remove();
74544
74545             // Enter
74546             var enter = items.enter()
74547                 .append('div')
74548                 .attr('class', 'feature-list-item')
74549                 .on('click', selectEntity);
74550
74551             var label = enter
74552                 .append('button')
74553                 .attr('class', 'label');
74554
74555             enter
74556                 .append('button')
74557                 .attr('class', 'close')
74558                 .on('click', deselectEntity)
74559                 .call(svgIcon('#icon-close'));
74560
74561             label
74562                 .append('span')
74563                 .attr('class', 'entity-geom-icon')
74564                 .call(svgIcon('', 'pre-text'));
74565
74566             label
74567                 .append('span')
74568                 .attr('class', 'entity-type');
74569
74570             label
74571                 .append('span')
74572                 .attr('class', 'entity-name');
74573
74574             // Update
74575             items = items.merge(enter);
74576
74577             items.selectAll('.entity-geom-icon use')
74578                 .attr('href', function() {
74579                     var entity = this.parentNode.parentNode.__data__;
74580                     return '#icon-' + context.geometry(entity.id);
74581                 });
74582
74583             items.selectAll('.entity-type')
74584                 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
74585
74586             items.selectAll('.entity-name')
74587                 .text(function(entity) { return utilDisplayName(entity); });
74588         }
74589     }
74590
74591     return selectionList;
74592 }
74593
74594 function uiSourceSwitch(context) {
74595     var keys$$1;
74596
74597
74598     function click() {
74599         event.preventDefault();
74600
74601         if (context.history().hasChanges() &&
74602             !window.confirm(t('source_switch.lose_changes'))) return;
74603
74604         var live = select(this)
74605             .classed('live');
74606
74607         context.history().clearSaved();
74608         context.connection().switch(live ? keys$$1[1] : keys$$1[0]);
74609         context.enter(modeBrowse(context));
74610         context.flush();
74611
74612         select(this)
74613             .text(live ? t('source_switch.dev') : t('source_switch.live'))
74614             .classed('live', !live);
74615     }
74616
74617     var sourceSwitch = function(selection$$1) {
74618         selection$$1
74619             .append('a')
74620             .attr('href', '#')
74621             .text(t('source_switch.live'))
74622             .classed('live', true)
74623             .attr('tabindex', -1)
74624             .on('click', click);
74625     };
74626
74627
74628     sourceSwitch.keys = function(_) {
74629         if (!arguments.length) return keys$$1;
74630         keys$$1 = _;
74631         return sourceSwitch;
74632     };
74633
74634
74635     return sourceSwitch;
74636 }
74637
74638 function uiSuccess(context) {
74639     var dispatch$$1 = dispatch('cancel'),
74640         changeset;
74641
74642
74643     function success(selection$$1) {
74644         var header = selection$$1
74645             .append('div')
74646             .attr('class', 'header fillL');
74647
74648         header
74649             .append('button')
74650             .attr('class', 'fr')
74651             .on('click', function() { dispatch$$1.call('cancel'); })
74652             .call(svgIcon('#icon-close'));
74653
74654         header
74655             .append('h3')
74656             .text(t('success.just_edited'));
74657
74658         var body = selection$$1
74659             .append('div')
74660             .attr('class', 'body save-success fillL');
74661
74662         body
74663             .append('p')
74664             .html(t('success.help_html'));
74665
74666         body
74667             .append('a')
74668             .attr('class', 'details')
74669             .attr('target', '_blank')
74670             .attr('tabindex', -1)
74671             .call(svgIcon('#icon-out-link', 'inline'))
74672             .attr('href', t('success.help_link_url'))
74673             .append('span')
74674             .text(t('success.help_link_text'));
74675
74676         var osm = context.connection();
74677         if (!osm) return;
74678
74679         var changesetURL = osm.changesetURL(changeset.id);
74680
74681         var viewOnOsm = body
74682             .append('a')
74683             .attr('class', 'button col12 osm')
74684             .attr('target', '_blank')
74685             .attr('href', changesetURL);
74686
74687         viewOnOsm
74688             .append('svg')
74689             .attr('class', 'logo logo-osm')
74690             .append('use')
74691             .attr('xlink:href', '#logo-osm');
74692
74693         viewOnOsm
74694             .append('div')
74695             .text(t('success.view_on_osm'));
74696
74697         var message = (changeset.tags.comment || t('success.edited_osm')).substring(0, 130) +
74698             ' ' + changesetURL;
74699
74700         var sharing = {
74701             facebook: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL),
74702             twitter: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message),
74703             google: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL)
74704         };
74705
74706         body.selectAll('.button.social')
74707             .data(entries(sharing))
74708             .enter()
74709             .append('a')
74710             .attr('class', 'button social col4')
74711             .attr('target', '_blank')
74712             .attr('href', function(d) { return d.value; })
74713             .call(tooltip()
74714                 .title(function(d) { return t('success.' + d.key); })
74715                 .placement('bottom'))
74716             .each(function(d) { select(this).call(svgIcon('#logo-' + d.key, 'social')); });
74717     }
74718
74719
74720     success.changeset = function(_) {
74721         if (!arguments.length) return changeset;
74722         changeset = _;
74723         return success;
74724     };
74725
74726
74727     return utilRebind(success, dispatch$$1, 'on');
74728 }
74729
74730 function coreHistory(context) {
74731     var imageryUsed = ['Bing'],
74732         dispatch$$1 = dispatch('change', 'undone', 'redone'),
74733         lock = utilSessionMutex('lock'),
74734         duration = 150,
74735         checkpoints = {},
74736         stack$$1, index, tree$$1;
74737
74738
74739     // internal _act, accepts list of actions and eased time
74740     function _act(actions, t) {
74741         actions = Array.prototype.slice.call(actions);
74742
74743         var annotation;
74744
74745         if (!lodash.isFunction(lodash.last(actions))) {
74746             annotation = actions.pop();
74747         }
74748
74749         stack$$1[index].transform = context.projection.transform();
74750         stack$$1[index].selectedIDs = context.selectedIDs();
74751
74752         var graph = stack$$1[index].graph;
74753         for (var i = 0; i < actions.length; i++) {
74754             graph = actions[i](graph, t);
74755         }
74756
74757         return {
74758             graph: graph,
74759             annotation: annotation,
74760             imageryUsed: imageryUsed
74761         };
74762     }
74763
74764
74765     // internal _perform with eased time
74766     function _perform(args, t) {
74767         var previous = stack$$1[index].graph;
74768         stack$$1 = stack$$1.slice(0, index + 1);
74769         stack$$1.push(_act(args, t));
74770         index++;
74771         return change(previous);
74772     }
74773
74774
74775     // internal _replace with eased time
74776     function _replace(args, t) {
74777         var previous = stack$$1[index].graph;
74778         // assert(index == stack.length - 1)
74779         stack$$1[index] = _act(args, t);
74780         return change(previous);
74781     }
74782
74783
74784     // internal _overwrite with eased time
74785     function _overwrite(args, t) {
74786         var previous = stack$$1[index].graph;
74787         if (index > 0) {
74788             index--;
74789             stack$$1.pop();
74790         }
74791         stack$$1 = stack$$1.slice(0, index + 1);
74792         stack$$1.push(_act(args, t));
74793         index++;
74794         return change(previous);
74795     }
74796
74797
74798     // determine diffrence and dispatch a change event
74799     function change(previous) {
74800         var difference = coreDifference(previous, history.graph());
74801         dispatch$$1.call('change', this, difference);
74802         return difference;
74803     }
74804
74805
74806     // iD uses namespaced keys so multiple installations do not conflict
74807     function getKey(n) {
74808         return 'iD_' + window.location.origin + '_' + n;
74809     }
74810
74811
74812     var history = {
74813
74814         graph: function() {
74815             return stack$$1[index].graph;
74816         },
74817
74818
74819         base: function() {
74820             return stack$$1[0].graph;
74821         },
74822
74823
74824         merge: function(entities, extent$$1) {
74825             stack$$1[0].graph.rebase(entities, lodash.map(stack$$1, 'graph'), false);
74826             tree$$1.rebase(entities, false);
74827
74828             dispatch$$1.call('change', this, undefined, extent$$1);
74829         },
74830
74831
74832         perform: function() {
74833             // complete any transition already in progress
74834             select(document).interrupt('history.perform');
74835
74836             var transitionable = false,
74837                 action0 = arguments[0];
74838
74839             if (arguments.length === 1 ||
74840                 arguments.length === 2 && !lodash.isFunction(arguments[1])) {
74841                 transitionable = !!action0.transitionable;
74842             }
74843
74844             if (transitionable) {
74845                 var origArguments = arguments;
74846                 select(document)
74847                     .transition('history.perform')
74848                     .duration(duration)
74849                     .ease(linear$1)
74850                     .tween('history.tween', function() {
74851                         return function(t) {
74852                             if (t < 1) _overwrite([action0], t);
74853                         };
74854                     })
74855                     .on('start', function() {
74856                         _perform([action0], 0);
74857                     })
74858                     .on('end interrupt', function() {
74859                         _overwrite(origArguments, 1);
74860                     });
74861
74862             } else {
74863                 return _perform(arguments);
74864             }
74865         },
74866
74867
74868         replace: function() {
74869             select(document).interrupt('history.perform');
74870             return _replace(arguments, 1);
74871         },
74872
74873
74874         // Same as calling pop and then perform
74875         overwrite: function() {
74876             select(document).interrupt('history.perform');
74877             return _overwrite(arguments, 1);
74878         },
74879
74880
74881         pop: function(n) {
74882             select(document).interrupt('history.perform');
74883
74884             var previous = stack$$1[index].graph;
74885             if (isNaN(+n) || +n < 0) {
74886                 n = 1;
74887             }
74888             while (n-- > 0 && index > 0) {
74889                 index--;
74890                 stack$$1.pop();
74891             }
74892             return change(previous);
74893         },
74894
74895
74896         // Back to the previous annotated state or index = 0.
74897         undo: function() {
74898             select(document).interrupt('history.perform');
74899
74900             var previous = stack$$1[index].graph;
74901             while (index > 0) {
74902                 index--;
74903                 if (stack$$1[index].annotation) break;
74904             }
74905
74906             dispatch$$1.call('undone', this, stack$$1[index]);
74907             return change(previous);
74908         },
74909
74910
74911         // Forward to the next annotated state.
74912         redo: function() {
74913             select(document).interrupt('history.perform');
74914
74915             var previous = stack$$1[index].graph;
74916             var tryIndex = index;
74917             while (tryIndex < stack$$1.length - 1) {
74918                 tryIndex++;
74919                 if (stack$$1[tryIndex].annotation) {
74920                     index = tryIndex;
74921                     dispatch$$1.call('redone', this, stack$$1[index]);
74922                     break;
74923                 }
74924             }
74925
74926             return change(previous);
74927         },
74928
74929
74930         undoAnnotation: function() {
74931             var i = index;
74932             while (i >= 0) {
74933                 if (stack$$1[i].annotation) return stack$$1[i].annotation;
74934                 i--;
74935             }
74936         },
74937
74938
74939         redoAnnotation: function() {
74940             var i = index + 1;
74941             while (i <= stack$$1.length - 1) {
74942                 if (stack$$1[i].annotation) return stack$$1[i].annotation;
74943                 i++;
74944             }
74945         },
74946
74947
74948         intersects: function(extent$$1) {
74949             return tree$$1.intersects(extent$$1, stack$$1[index].graph);
74950         },
74951
74952
74953         difference: function() {
74954             var base = stack$$1[0].graph,
74955                 head = stack$$1[index].graph;
74956             return coreDifference(base, head);
74957         },
74958
74959
74960         changes: function(action) {
74961             var base = stack$$1[0].graph,
74962                 head = stack$$1[index].graph;
74963
74964             if (action) {
74965                 head = action(head);
74966             }
74967
74968             var difference = coreDifference(base, head);
74969
74970             return {
74971                 modified: difference.modified(),
74972                 created: difference.created(),
74973                 deleted: difference.deleted()
74974             };
74975         },
74976
74977
74978         validate: function(changes) {
74979             return lodash(Validations)
74980                 .map(function(fn) { return fn()(changes, stack$$1[index].graph); })
74981                 .flatten()
74982                 .value();
74983         },
74984
74985
74986         hasChanges: function() {
74987             return this.difference().length() > 0;
74988         },
74989
74990
74991         imageryUsed: function(sources) {
74992             if (sources) {
74993                 imageryUsed = sources;
74994                 return history;
74995             } else {
74996                 return lodash(stack$$1.slice(1, index + 1))
74997                     .map('imageryUsed')
74998                     .flatten()
74999                     .uniq()
75000                     .without(undefined, 'Custom')
75001                     .value();
75002             }
75003         },
75004
75005
75006         // save the current history state
75007         checkpoint: function(key) {
75008             checkpoints[key] = {
75009                 stack: lodash.cloneDeep(stack$$1),
75010                 index: index
75011             };
75012             return history;
75013         },
75014
75015
75016         // restore history state to a given checkpoint or reset completely
75017         reset: function(key) {
75018             if (key !== undefined && checkpoints.hasOwnProperty(key)) {
75019                 stack$$1 = lodash.cloneDeep(checkpoints[key].stack);
75020                 index = checkpoints[key].index;
75021             } else {
75022                 stack$$1 = [{graph: coreGraph$$1()}];
75023                 index = 0;
75024                 tree$$1 = coreTree(stack$$1[0].graph);
75025                 checkpoints = {};
75026             }
75027             dispatch$$1.call('change');
75028             return history;
75029         },
75030
75031
75032         toIntroGraph: function() {
75033             var nextId = { n: 0, r: 0, w: 0 },
75034                 permIds = {},
75035                 graph = this.graph(),
75036                 baseEntities = {};
75037
75038             // clone base entities..
75039             lodash.forEach(graph.base().entities, function(entity) {
75040                 var copy = lodash.cloneDeepWith(entity, customizer);
75041                 baseEntities[copy.id] = copy;
75042             });
75043
75044             // replace base entities with head entities..
75045             lodash.forEach(graph.entities, function(entity, id) {
75046                 if (entity) {
75047                     var copy = lodash.cloneDeepWith(entity, customizer);
75048                     baseEntities[copy.id] = copy;
75049                 } else {
75050                     delete baseEntities[id];
75051                 }
75052             });
75053
75054             // swap temporary for permanent ids..
75055             lodash.forEach(baseEntities, function(entity) {
75056                 if (Array.isArray(entity.nodes)) {
75057                     entity.nodes = entity.nodes.map(function(node) {
75058                         return permIds[node] || node;
75059                     });
75060                 }
75061                 if (Array.isArray(entity.members)) {
75062                     entity.members = entity.members.map(function(member) {
75063                         member.id = permIds[member.id] || member.id;
75064                         return member;
75065                     });
75066                 }
75067             });
75068
75069             return JSON.stringify({ dataIntroGraph: baseEntities });
75070
75071
75072             function customizer(src) {
75073                 var copy = lodash.omit(lodash.cloneDeep(src), ['type', 'user', 'v', 'version', 'visible']);
75074                 if (lodash.isEmpty(copy.tags)) {
75075                     delete copy.tags;
75076                 }
75077
75078                 if (Array.isArray(copy.loc)) {
75079                     copy.loc[0] = +copy.loc[0].toFixed(6);
75080                     copy.loc[1] = +copy.loc[1].toFixed(6);
75081                 }
75082
75083                 var match = src.id.match(/([nrw])-\d*/);  // temporary id
75084                 if (match !== null) {
75085                     var nrw = match[1], permId;
75086                     do { permId = nrw + (++nextId[nrw]); }
75087                     while (baseEntities.hasOwnProperty(permId));
75088
75089                     copy.id = permIds[src.id] = permId;
75090                 }
75091                 return copy;
75092             }
75093         },
75094
75095
75096         toJSON: function() {
75097             if (!this.hasChanges()) return;
75098
75099             var allEntities = {},
75100                 baseEntities = {},
75101                 base = stack$$1[0];
75102
75103             var s = stack$$1.map(function(i) {
75104                 var modified = [], deleted = [];
75105
75106                 lodash.forEach(i.graph.entities, function(entity, id) {
75107                     if (entity) {
75108                         var key = osmEntity$$1.key(entity);
75109                         allEntities[key] = entity;
75110                         modified.push(key);
75111                     } else {
75112                         deleted.push(id);
75113                     }
75114
75115                     // make sure that the originals of changed or deleted entities get merged
75116                     // into the base of the stack after restoring the data from JSON.
75117                     if (id in base.graph.entities) {
75118                         baseEntities[id] = base.graph.entities[id];
75119                     }
75120                     // get originals of parent entities too
75121                     lodash.forEach(base.graph._parentWays[id], function(parentId) {
75122                         if (parentId in base.graph.entities) {
75123                             baseEntities[parentId] = base.graph.entities[parentId];
75124                         }
75125                     });
75126                 });
75127
75128                 var x = {};
75129
75130                 if (modified.length) x.modified = modified;
75131                 if (deleted.length) x.deleted = deleted;
75132                 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
75133                 if (i.annotation) x.annotation = i.annotation;
75134
75135                 return x;
75136             });
75137
75138             return JSON.stringify({
75139                 version: 3,
75140                 entities: lodash.values(allEntities),
75141                 baseEntities: lodash.values(baseEntities),
75142                 stack: s,
75143                 nextIDs: osmEntity$$1.id.next,
75144                 index: index
75145             });
75146         },
75147
75148
75149         fromJSON: function(json$$1, loadChildNodes) {
75150             var h = JSON.parse(json$$1),
75151                 loadComplete = true;
75152
75153             osmEntity$$1.id.next = h.nextIDs;
75154             index = h.index;
75155
75156             if (h.version === 2 || h.version === 3) {
75157                 var allEntities = {};
75158
75159                 h.entities.forEach(function(entity) {
75160                     allEntities[osmEntity$$1.key(entity)] = osmEntity$$1(entity);
75161                 });
75162
75163                 if (h.version === 3) {
75164                     // This merges originals for changed entities into the base of
75165                     // the stack even if the current stack doesn't have them (for
75166                     // example when iD has been restarted in a different region)
75167                     var baseEntities = h.baseEntities.map(function(d) { return osmEntity$$1(d); });
75168                     stack$$1[0].graph.rebase(baseEntities, lodash.map(stack$$1, 'graph'), true);
75169                     tree$$1.rebase(baseEntities, true);
75170
75171                     // When we restore a modified way, we also need to fetch any missing
75172                     // childnodes that would normally have been downloaded with it.. #2142
75173                     if (loadChildNodes) {
75174                         var osm = context.connection();
75175                         var missing =  lodash(baseEntities)
75176                                 .filter({ type: 'way' })
75177                                 .map('nodes')
75178                                 .flatten()
75179                                 .uniq()
75180                                 .reject(function(n) { return stack$$1[0].graph.hasEntity(n); })
75181                                 .value();
75182
75183                         if (!lodash.isEmpty(missing) && osm) {
75184                             loadComplete = false;
75185                             context.redrawEnable(false);
75186
75187                             var loading = uiLoading(context).blocking(true);
75188                             context.container().call(loading);
75189
75190                             var childNodesLoaded = function(err, result) {
75191                                 if (!err) {
75192                                     var visible = lodash.groupBy(result.data, 'visible');
75193                                     if (!lodash.isEmpty(visible.true)) {
75194                                         missing = lodash.difference(missing, lodash.map(visible.true, 'id'));
75195                                         stack$$1[0].graph.rebase(visible.true, lodash.map(stack$$1, 'graph'), true);
75196                                         tree$$1.rebase(visible.true, true);
75197                                     }
75198
75199                                     // fetch older versions of nodes that were deleted..
75200                                     lodash.each(visible.false, function(entity) {
75201                                         osm.loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
75202                                     });
75203                                 }
75204
75205                                 if (err || lodash.isEmpty(missing)) {
75206                                     loading.close();
75207                                     context.redrawEnable(true);
75208                                     dispatch$$1.call('change');
75209                                 }
75210                             };
75211
75212                             osm.loadMultiple(missing, childNodesLoaded);
75213                         }
75214                     }
75215                 }
75216
75217                 stack$$1 = h.stack.map(function(d) {
75218                     var entities = {}, entity;
75219
75220                     if (d.modified) {
75221                         d.modified.forEach(function(key) {
75222                             entity = allEntities[key];
75223                             entities[entity.id] = entity;
75224                         });
75225                     }
75226
75227                     if (d.deleted) {
75228                         d.deleted.forEach(function(id) {
75229                             entities[id] = undefined;
75230                         });
75231                     }
75232
75233                     return {
75234                         graph: coreGraph$$1(stack$$1[0].graph).load(entities),
75235                         annotation: d.annotation,
75236                         imageryUsed: d.imageryUsed
75237                     };
75238                 });
75239
75240             } else { // original version
75241                 stack$$1 = h.stack.map(function(d) {
75242                     var entities = {};
75243
75244                     for (var i in d.entities) {
75245                         var entity = d.entities[i];
75246                         entities[i] = entity === 'undefined' ? undefined : osmEntity$$1(entity);
75247                     }
75248
75249                     d.graph = coreGraph$$1(stack$$1[0].graph).load(entities);
75250                     return d;
75251                 });
75252             }
75253
75254             if (loadComplete) {
75255                 dispatch$$1.call('change');
75256             }
75257
75258             return history;
75259         },
75260
75261
75262         save: function() {
75263             if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
75264             return history;
75265         },
75266
75267
75268         clearSaved: function() {
75269             context.debouncedSave.cancel();
75270             if (lock.locked()) context.storage(getKey('saved_history'), null);
75271             return history;
75272         },
75273
75274
75275         lock: function() {
75276             return lock.lock();
75277         },
75278
75279
75280         unlock: function() {
75281             lock.unlock();
75282         },
75283
75284
75285         // is iD not open in another window and it detects that
75286         // there's a history stored in localStorage that's recoverable?
75287         restorableChanges: function() {
75288             return lock.locked() && !!context.storage(getKey('saved_history'));
75289         },
75290
75291
75292         // load history from a version stored in localStorage
75293         restore: function() {
75294             if (!lock.locked()) return;
75295
75296             var json$$1 = context.storage(getKey('saved_history'));
75297             if (json$$1) history.fromJSON(json$$1, true);
75298         },
75299
75300
75301         _getKey: getKey
75302
75303     };
75304
75305
75306     history.reset();
75307
75308     return utilRebind(history, dispatch$$1, 'on');
75309 }
75310
75311 function presetCollection(collection) {
75312     var maxSearchResults = 50,
75313         maxSuggestionResults = 10;
75314
75315     var presets = {
75316
75317         collection: collection,
75318
75319
75320         item: function(id) {
75321             return lodash.find(this.collection, function(d) {
75322                 return d.id === id;
75323             });
75324         },
75325
75326
75327         matchGeometry: function(geometry) {
75328             return presetCollection(this.collection.filter(function(d) {
75329                 return d.matchGeometry(geometry);
75330             }));
75331         },
75332
75333
75334         search: function(value, geometry) {
75335             if (!value) return this;
75336
75337             function leading(a) {
75338                 var index = a.indexOf(value);
75339                 return index === 0 || a[index - 1] === ' ';
75340             }
75341
75342             function suggestionName(name) {
75343                 var nameArray = name.split(' - ');
75344                 if (nameArray.length > 1) {
75345                     name = nameArray.slice(0, nameArray.length - 1).join(' - ');
75346                 }
75347                 return name.toLowerCase();
75348             }
75349
75350
75351             value = value.toLowerCase();
75352
75353             var searchable = lodash.filter(this.collection, function(a) {
75354                     return a.searchable !== false && a.suggestion !== true;
75355                 }),
75356                 suggestions = lodash.filter(this.collection, function(a) {
75357                     return a.suggestion === true;
75358                 });
75359
75360
75361             // matches value to preset.name
75362             var leading_name = lodash.filter(searchable, function(a) {
75363                     return leading(a.name().toLowerCase());
75364                 }).sort(function(a, b) {
75365                     var i;
75366                     i = b.originalScore - a.originalScore;
75367                     if (i !== 0) return i;
75368
75369                     i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value);
75370                     if (i !== 0) return i;
75371
75372                     return a.name().length - b.name().length;
75373                 });
75374
75375             // matches value to preset.terms values
75376             var leading_terms = lodash.filter(searchable, function(a) {
75377                     return lodash.some(a.terms() || [], leading);
75378                 });
75379
75380             // matches value to preset.tags values
75381             var leading_tag_values = lodash.filter(searchable, function(a) {
75382                     return lodash.some(lodash.without(lodash.values(a.tags || {}), '*'), leading);
75383                 });
75384
75385
75386             // finds close matches to value in preset.name
75387             var similar_name = searchable.map(function(a) {
75388                     return {
75389                         preset: a,
75390                         dist: utilEditDistance(value, a.name())
75391                     };
75392                 }).filter(function(a) {
75393                     return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
75394                 }).sort(function(a, b) {
75395                     return a.dist - b.dist;
75396                 }).map(function(a) {
75397                     return a.preset;
75398                 });
75399
75400             // finds close matches to value in preset.terms
75401             var similar_terms = lodash.filter(searchable, function(a) {
75402                     return lodash.some(a.terms() || [], function(b) {
75403                         return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
75404                     });
75405                 });
75406
75407             var leading_suggestions = lodash.filter(suggestions, function(a) {
75408                     return leading(suggestionName(a.name()));
75409                 }).sort(function(a, b) {
75410                     a = suggestionName(a.name());
75411                     b = suggestionName(b.name());
75412                     var i = a.indexOf(value) - b.indexOf(value);
75413                     if (i === 0) return a.length - b.length;
75414                     else return i;
75415                 });
75416
75417             var similar_suggestions = suggestions.map(function(a) {
75418                     return {
75419                         preset: a,
75420                         dist: utilEditDistance(value, suggestionName(a.name()))
75421                     };
75422                 }).filter(function(a) {
75423                     return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
75424                 }).sort(function(a, b) {
75425                     return a.dist - b.dist;
75426                 }).map(function(a) {
75427                     return a.preset;
75428                 });
75429
75430             var other = presets.item(geometry);
75431
75432             var results = leading_name.concat(
75433                     leading_terms,
75434                     leading_tag_values,
75435                     leading_suggestions.slice(0, maxSuggestionResults + 5),
75436                     similar_name,
75437                     similar_terms,
75438                     similar_suggestions.slice(0, maxSuggestionResults)
75439                 ).slice(0, maxSearchResults - 1);
75440
75441             return presetCollection(lodash.uniq(results.concat(other)));
75442         }
75443     };
75444
75445
75446     return presets;
75447 }
75448
75449 function presetCategory(id, category, all) {
75450     category = lodash.clone(category);
75451
75452     category.id = id;
75453
75454
75455     category.members = presetCollection(category.members.map(function(id) {
75456         return all.item(id);
75457     }));
75458
75459
75460     category.matchGeometry = function(geometry) {
75461         return category.geometry.indexOf(geometry) >= 0;
75462     };
75463
75464
75465     category.matchScore = function() {
75466         return -1;
75467     };
75468
75469
75470     category.name = function() {
75471         return t('presets.categories.' + id + '.name', {'default': id});
75472     };
75473
75474
75475     category.terms = function() {
75476         return [];
75477     };
75478
75479
75480     return category;
75481 }
75482
75483 function presetField(id, field) {
75484     field = lodash.clone(field);
75485
75486     field.id = id;
75487
75488
75489     field.matchGeometry = function(geometry) {
75490         return !field.geometry || field.geometry === geometry;
75491     };
75492
75493
75494     field.t = function(scope, options) {
75495         return t('presets.fields.' + id + '.' + scope, options);
75496     };
75497
75498
75499     field.label = function() {
75500         return field.t('label', {'default': id});
75501     };
75502
75503
75504     var placeholder = field.placeholder;
75505     field.placeholder = function() {
75506         return field.t('placeholder', {'default': placeholder});
75507     };
75508
75509
75510     return field;
75511 }
75512
75513 function presetPreset(id, preset, fields) {
75514     preset = lodash.clone(preset);
75515
75516     preset.id = id;
75517     preset.fields = (preset.fields || []).map(getFields);
75518     preset.geometry = (preset.geometry || []);
75519
75520
75521     function getFields(f) {
75522         return fields[f];
75523     }
75524
75525
75526     preset.matchGeometry = function(geometry) {
75527         return preset.geometry.indexOf(geometry) >= 0;
75528     };
75529
75530
75531     preset.originalScore = preset.matchScore || 1;
75532
75533
75534     preset.matchScore = function(entity) {
75535         var tags = preset.tags,
75536             score = 0;
75537
75538         for (var t$$1 in tags) {
75539             if (entity.tags[t$$1] === tags[t$$1]) {
75540                 score += preset.originalScore;
75541             } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
75542                 score += preset.originalScore / 2;
75543             } else {
75544                 return -1;
75545             }
75546         }
75547
75548         return score;
75549     };
75550
75551
75552     preset.t = function(scope, options) {
75553         return t('presets.presets.' + id + '.' + scope, options);
75554     };
75555
75556
75557     var name = preset.name || '';
75558     preset.name = function() {
75559         if (preset.suggestion) {
75560             id = id.split('/');
75561             id = id[0] + '/' + id[1];
75562             return name + ' - ' + t('presets.presets.' + id + '.name');
75563         }
75564         return preset.t('name', {'default': name});
75565     };
75566
75567
75568     preset.terms = function() {
75569         return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/);
75570     };
75571
75572
75573     preset.isFallback = function() {
75574         var tagCount = Object.keys(preset.tags).length;
75575         return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
75576     };
75577
75578
75579     var reference = preset.reference || {};
75580     preset.reference = function(geometry) {
75581         var key = reference.key || Object.keys(lodash.omit(preset.tags, 'name'))[0],
75582             value = reference.value || preset.tags[key];
75583
75584         if (geometry === 'relation' && key === 'type') {
75585             if (value in preset.tags) {
75586                 key = value;
75587                 value = preset.tags[key];
75588             } else {
75589                 return { rtype: value };
75590             }
75591         }
75592
75593         if (value === '*') {
75594             return { key: key };
75595         } else {
75596             return { key: key, value: value };
75597         }
75598     };
75599
75600
75601     var removeTags = preset.removeTags || preset.tags;
75602     preset.removeTags = function(tags, geometry) {
75603         tags = lodash.omit(tags, lodash.keys(removeTags));
75604
75605         for (var f in preset.fields) {
75606             var field = preset.fields[f];
75607             if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
75608                 delete tags[field.key];
75609             }
75610         }
75611
75612         delete tags.area;
75613         return tags;
75614     };
75615
75616
75617     var applyTags = preset.addTags || preset.tags;
75618     preset.applyTags = function(tags, geometry) {
75619         var k;
75620
75621         tags = lodash.clone(tags);
75622
75623         for (k in applyTags) {
75624             if (applyTags[k] === '*') {
75625                 tags[k] = 'yes';
75626             } else {
75627                 tags[k] = applyTags[k];
75628             }
75629         }
75630
75631         // Add area=yes if necessary.
75632         // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
75633         // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
75634         // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
75635         delete tags.area;
75636         if (geometry === 'area') {
75637             var needsAreaTag = true;
75638             if (preset.geometry.indexOf('line') === -1) {
75639                 for (k in applyTags) {
75640                     if (k in areaKeys) {
75641                         needsAreaTag = false;
75642                         break;
75643                     }
75644                 }
75645             }
75646             if (needsAreaTag) {
75647                 tags.area = 'yes';
75648             }
75649         }
75650
75651         for (var f in preset.fields) {
75652             var field = preset.fields[f];
75653             if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
75654                 tags[field.key] = field.default;
75655             }
75656         }
75657
75658         return tags;
75659     };
75660
75661
75662     return preset;
75663 }
75664
75665 function presetIndex() {
75666     // a presetCollection with methods for
75667     // loading new data and returning defaults
75668
75669     var all = presetCollection([]),
75670         defaults = { area: all, line: all, point: all, vertex: all, relation: all },
75671         fields = {},
75672         universal = [],
75673         recent = presetCollection([]);
75674
75675     // Index of presets by (geometry, tag key).
75676     var index = {
75677         point: {},
75678         vertex: {},
75679         line: {},
75680         area: {},
75681         relation: {}
75682     };
75683
75684     all.match = function(entity, resolver) {
75685         var geometry = entity.geometry(resolver);
75686
75687         // Treat entities on addr:interpolation lines as points, not vertices (#3241)
75688         if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
75689             geometry = 'point';
75690         }
75691
75692         var geometryMatches = index[geometry],
75693             best = -1,
75694             match;
75695
75696         for (var k in entity.tags) {
75697             var keyMatches = geometryMatches[k];
75698             if (!keyMatches) continue;
75699
75700             for (var i = 0; i < keyMatches.length; i++) {
75701                 var score = keyMatches[i].matchScore(entity);
75702                 if (score > best) {
75703                     best = score;
75704                     match = keyMatches[i];
75705                 }
75706             }
75707         }
75708
75709         return match || all.item(geometry);
75710     };
75711
75712
75713     // Because of the open nature of tagging, iD will never have a complete
75714     // list of tags used in OSM, so we want it to have logic like "assume
75715     // that a closed way with an amenity tag is an area, unless the amenity
75716     // is one of these specific types". This function computes a structure
75717     // that allows testing of such conditions, based on the presets designated
75718     // as as supporting (or not supporting) the area geometry.
75719     //
75720     // The returned object L is a whitelist/blacklist of tags. A closed way
75721     // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
75722     // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
75723     // and the subkeys form the blacklist.
75724     all.areaKeys = function() {
75725         var areaKeys = {},
75726             ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],  // probably a line..
75727             presets = lodash.reject(all.collection, 'suggestion');
75728
75729         // whitelist
75730         presets.forEach(function(d) {
75731             for (var key in d.tags) break;
75732             if (!key) return;
75733             if (ignore.indexOf(key) !== -1) return;
75734
75735             if (d.geometry.indexOf('area') !== -1) {    // probably an area..
75736                 areaKeys[key] = areaKeys[key] || {};
75737             }
75738         });
75739
75740         // blacklist
75741         presets.forEach(function(d) {
75742             for (var key in d.tags) break;
75743             if (!key) return;
75744             if (ignore.indexOf(key) !== -1) return;
75745
75746             var value = d.tags[key];
75747             if (key in areaKeys &&                      // probably an area...
75748                 d.geometry.indexOf('line') !== -1 &&    // but sometimes a line
75749                 value !== '*') {
75750                 areaKeys[key][value] = true;
75751             }
75752         });
75753
75754         return areaKeys;
75755     };
75756
75757
75758     all.init = function() {
75759         var d = data.presets;
75760
75761         all.collection = [];
75762         recent.collection = [];
75763         fields = {};
75764         universal = [];
75765         index = { point: {}, vertex: {}, line: {}, area: {}, relation: {} };
75766
75767         if (d.fields) {
75768             lodash.forEach(d.fields, function(d, id) {
75769                 fields[id] = presetField(id, d);
75770                 if (d.universal) universal.push(fields[id]);
75771             });
75772         }
75773
75774         if (d.presets) {
75775             lodash.forEach(d.presets, function(d, id) {
75776                 all.collection.push(presetPreset(id, d, fields));
75777             });
75778         }
75779
75780         if (d.categories) {
75781             lodash.forEach(d.categories, function(d, id) {
75782                 all.collection.push(presetCategory(id, d, all));
75783             });
75784         }
75785
75786         if (d.defaults) {
75787             var getItem = lodash.bind(all.item, all);
75788             defaults = {
75789                 area: presetCollection(d.defaults.area.map(getItem)),
75790                 line: presetCollection(d.defaults.line.map(getItem)),
75791                 point: presetCollection(d.defaults.point.map(getItem)),
75792                 vertex: presetCollection(d.defaults.vertex.map(getItem)),
75793                 relation: presetCollection(d.defaults.relation.map(getItem))
75794             };
75795         }
75796
75797         for (var i = 0; i < all.collection.length; i++) {
75798             var preset = all.collection[i],
75799                 geometry = preset.geometry;
75800
75801             for (var j = 0; j < geometry.length; j++) {
75802                 var g = index[geometry[j]];
75803                 for (var k in preset.tags) {
75804                     (g[k] = g[k] || []).push(preset);
75805                 }
75806             }
75807         }
75808
75809         return all;
75810     };
75811
75812     all.field = function(id) {
75813         return fields[id];
75814     };
75815
75816     all.universal = function() {
75817         return universal;
75818     };
75819
75820     all.defaults = function(geometry, n) {
75821         var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
75822             def = lodash.uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
75823         return presetCollection(lodash.uniq(rec.concat(def).concat(all.item(geometry))));
75824     };
75825
75826     all.choose = function(preset) {
75827         if (!preset.isFallback()) {
75828             recent = presetCollection(lodash.uniq([preset].concat(recent.collection)));
75829         }
75830         return all;
75831     };
75832
75833     return all;
75834 }
75835
75836 var areaKeys = {};
75837
75838 function setAreaKeys(value) {
75839     areaKeys = value;
75840 }
75841
75842
75843 function coreContext() {
75844     var context = {};
75845     context.version = '2.4.0';
75846
75847     // create a special translation that contains the keys in place of the strings
75848     var tkeys = lodash.cloneDeep(en);
75849     var parents = [];
75850
75851     function traverser(v, k, obj) {
75852         parents.push(k);
75853         if (lodash.isObject(v)) {
75854             lodash.forOwn(v, traverser);
75855         } else if (lodash.isString(v)) {
75856             obj[k] = parents.join('.');
75857         }
75858         parents.pop();
75859     }
75860
75861     lodash.forOwn(tkeys, traverser);
75862     addTranslation('_tkeys_', tkeys);
75863
75864     addTranslation('en', en);
75865     setLocale('en');
75866
75867     var dispatch$$1 = dispatch('enter', 'exit', 'change');
75868
75869     // https://github.com/openstreetmap/iD/issues/772
75870     // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
75871     var storage;
75872     try { storage = localStorage; } catch (e) {}  // eslint-disable-line no-empty
75873     storage = storage || (function() {
75874         var s = {};
75875         return {
75876             getItem: function(k) { return s[k]; },
75877             setItem: function(k, v) { s[k] = v; },
75878             removeItem: function(k) { delete s[k]; }
75879         };
75880     })();
75881
75882     context.storage = function(k, v) {
75883         try {
75884             if (arguments.length === 1) return storage.getItem(k);
75885             else if (v === null) storage.removeItem(k);
75886             else storage.setItem(k, v);
75887         } catch (e) {
75888             // localstorage quota exceeded
75889             /* eslint-disable no-console */
75890             if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
75891             /* eslint-enable no-console */
75892         }
75893     };
75894
75895
75896     /* Straight accessors. Avoid using these if you can. */
75897     var ui, connection, history;
75898     context.ui = function() { return ui; };
75899     context.connection = function() { return connection; };
75900     context.history = function() { return history; };
75901
75902
75903     /* Connection */
75904     var entitiesLoaded = utilCallWhenIdle(function entitiesLoaded(err, result) {
75905         if (!err) history.merge(result.data, result.extent);
75906     });
75907
75908     context.preauth = function(options) {
75909         if (connection) {
75910             connection.switch(options);
75911         }
75912         return context;
75913     };
75914
75915     context.loadTiles = utilCallWhenIdle(function(projection$$1, dimensions, callback) {
75916         function done(err, result) {
75917             entitiesLoaded(err, result);
75918             if (callback) callback(err, result);
75919         }
75920         if (connection) {
75921             connection.loadTiles(projection$$1, dimensions, done);
75922         }
75923     });
75924
75925     context.loadEntity = function(id, callback) {
75926         function done(err, result) {
75927             entitiesLoaded(err, result);
75928             if (callback) callback(err, result);
75929         }
75930         if (connection) {
75931             connection.loadEntity(id, done);
75932         }
75933     };
75934
75935     context.zoomToEntity = function(id, zoomTo) {
75936         if (zoomTo !== false) {
75937             this.loadEntity(id, function(err, result) {
75938                 if (err) return;
75939                 var entity = lodash.find(result.data, function(e) { return e.id === id; });
75940                 if (entity) { map.zoomTo(entity); }
75941             });
75942         }
75943
75944         map.on('drawn.zoomToEntity', function() {
75945             if (!context.hasEntity(id)) return;
75946             map.on('drawn.zoomToEntity', null);
75947             context.on('enter.zoomToEntity', null);
75948             context.enter(modeSelect(context, [id]));
75949         });
75950
75951         context.on('enter.zoomToEntity', function() {
75952             if (mode.id !== 'browse') {
75953                 map.on('drawn.zoomToEntity', null);
75954                 context.on('enter.zoomToEntity', null);
75955             }
75956         });
75957     };
75958
75959     var minEditableZoom = 16;
75960     context.minEditableZoom = function(_) {
75961         if (!arguments.length) return minEditableZoom;
75962         minEditableZoom = _;
75963         if (connection) {
75964             connection.tileZoom(_);
75965         }
75966         return context;
75967     };
75968
75969
75970     /* History */
75971     var inIntro = false;
75972     context.inIntro = function(_) {
75973         if (!arguments.length) return inIntro;
75974         inIntro = _;
75975         return context;
75976     };
75977
75978     context.save = function() {
75979         // no history save, no message onbeforeunload
75980         if (inIntro || select('.modal').size()) return;
75981
75982         var canSave;
75983         if (mode && mode.id === 'save') {
75984             canSave = false;
75985         } else {
75986             canSave = context.selectedIDs().every(function(id) {
75987                 var entity = context.hasEntity(id);
75988                 return entity && !entity.isDegenerate();
75989             });
75990         }
75991
75992         if (canSave) {
75993             history.save();
75994         }
75995         if (history.hasChanges()) {
75996             return t('save.unsaved_changes');
75997         }
75998     };
75999
76000
76001     /* Graph */
76002     context.hasEntity = function(id) {
76003         return history.graph().hasEntity(id);
76004     };
76005     context.entity = function(id) {
76006         return history.graph().entity(id);
76007     };
76008     context.childNodes = function(way) {
76009         return history.graph().childNodes(way);
76010     };
76011     context.geometry = function(id) {
76012         return context.entity(id).geometry(history.graph());
76013     };
76014
76015
76016     /* Modes */
76017     var mode;
76018     context.mode = function() {
76019         return mode;
76020     };
76021     context.enter = function(newMode) {
76022         if (mode) {
76023             mode.exit();
76024             dispatch$$1.call('exit', this, mode);
76025         }
76026
76027         mode = newMode;
76028         mode.enter();
76029         dispatch$$1.call('enter', this, mode);
76030     };
76031
76032     context.selectedIDs = function() {
76033         if (mode && mode.selectedIDs) {
76034             return mode.selectedIDs();
76035         } else {
76036             return [];
76037         }
76038     };
76039
76040
76041     /* Behaviors */
76042     context.install = function(behavior) {
76043         context.surface().call(behavior);
76044     };
76045     context.uninstall = function(behavior) {
76046         context.surface().call(behavior.off);
76047     };
76048
76049
76050     /* Copy/Paste */
76051     var copyIDs = [], copyGraph;
76052     context.copyGraph = function() { return copyGraph; };
76053     context.copyIDs = function(_) {
76054         if (!arguments.length) return copyIDs;
76055         copyIDs = _;
76056         copyGraph = history.graph();
76057         return context;
76058     };
76059
76060
76061     /* Background */
76062     var background;
76063     context.background = function() { return background; };
76064
76065
76066     /* Features */
76067     var features;
76068     context.features = function() { return features; };
76069     context.hasHiddenConnections = function(id) {
76070         var graph = history.graph(),
76071             entity = graph.entity(id);
76072         return features.hasHiddenConnections(entity, graph);
76073     };
76074
76075
76076     /* Presets */
76077     var presets;
76078     context.presets = function() { return presets; };
76079
76080
76081     /* Map */
76082     var map;
76083     context.map = function() { return map; };
76084     context.layers = function() { return map.layers; };
76085     context.surface = function() { return map.surface; };
76086     context.editable = function() { return map.editable(); };
76087     context.surfaceRect = function() {
76088         return map.surface.node().getBoundingClientRect();
76089     };
76090
76091
76092     /* Debug */
76093     var debugFlags = {
76094         tile: false,
76095         collision: false,
76096         imagery: false,
76097         imperial: false,
76098         driveLeft: false
76099     };
76100     context.debugFlags = function() {
76101         return debugFlags;
76102     };
76103     context.setDebug = function(flag, val) {
76104         if (arguments.length === 1) val = true;
76105         debugFlags[flag] = val;
76106         dispatch$$1.call('change');
76107         return context;
76108     };
76109     context.getDebug = function(flag) {
76110         return flag && debugFlags[flag];
76111     };
76112
76113
76114     /* Container */
76115     var container = select(document.body);
76116     context.container = function(_) {
76117         if (!arguments.length) return container;
76118         container = _;
76119         container.classed('id-container', true);
76120         return context;
76121     };
76122     var embed;
76123     context.embed = function(_) {
76124         if (!arguments.length) return embed;
76125         embed = _;
76126         return context;
76127     };
76128
76129
76130     /* Assets */
76131     var assetPath = '';
76132     context.assetPath = function(_) {
76133         if (!arguments.length) return assetPath;
76134         assetPath = _;
76135         return context;
76136     };
76137
76138     var assetMap = {};
76139     context.assetMap = function(_) {
76140         if (!arguments.length) return assetMap;
76141         assetMap = _;
76142         return context;
76143     };
76144
76145     context.asset = function(_) {
76146         var filename = assetPath + _;
76147         return assetMap[filename] || filename;
76148     };
76149
76150     context.imagePath = function(_) {
76151         return context.asset('img/' + _);
76152     };
76153
76154
76155     /* locales */
76156     // `locale` variable contains a "requested locale".
76157     // It won't become the `currentLocale` until after loadLocale() is called.
76158     var locale, localePath;
76159
76160     context.locale = function(loc, path$$1) {
76161         if (!arguments.length) return currentLocale;
76162         locale = loc;
76163         localePath = path$$1;
76164         return context;
76165     };
76166
76167     context.loadLocale = function(callback) {
76168         if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
76169             localePath = localePath || context.asset('locales/' + locale + '.json');
76170             json(localePath, function(err, result) {
76171                 if (!err) {
76172                     addTranslation(locale, result[locale]);
76173                     setLocale(locale);
76174                     utilDetect(true);
76175                 }
76176                 if (callback) {
76177                     callback(err);
76178                 }
76179             });
76180         } else {
76181             if (locale) {
76182                 setLocale(locale);
76183                 utilDetect(true);
76184             }
76185             if (callback) {
76186                 callback();
76187             }
76188         }
76189     };
76190
76191
76192     /* reset (aka flush) */
76193     context.reset = context.flush = function() {
76194         context.debouncedSave.cancel();
76195         lodash.each(services, function(service) {
76196             if (service && typeof service.reset === 'function') {
76197                 service.reset(context);
76198             }
76199         });
76200         features.reset();
76201         history.reset();
76202         return context;
76203     };
76204
76205
76206     /* Init */
76207
76208     context.projection = geoRawMercator();
76209     context.curtainProjection = geoRawMercator();
76210
76211     locale = utilDetect().locale;
76212     if (locale && !dataLocales.hasOwnProperty(locale)) {
76213         locale = locale.split('-')[0];
76214     }
76215
76216     history = coreHistory(context);
76217     context.graph = history.graph;
76218     context.changes = history.changes;
76219     context.intersects = history.intersects;
76220
76221     // Debounce save, since it's a synchronous localStorage write,
76222     // and history changes can happen frequently (e.g. when dragging).
76223     context.debouncedSave = lodash.debounce(context.save, 350);
76224     function withDebouncedSave(fn) {
76225         return function() {
76226             var result = fn.apply(history, arguments);
76227             context.debouncedSave();
76228             return result;
76229         };
76230     }
76231
76232     context.perform = withDebouncedSave(history.perform);
76233     context.replace = withDebouncedSave(history.replace);
76234     context.pop = withDebouncedSave(history.pop);
76235     context.overwrite = withDebouncedSave(history.overwrite);
76236     context.undo = withDebouncedSave(history.undo);
76237     context.redo = withDebouncedSave(history.redo);
76238
76239     ui = uiInit(context);
76240
76241     connection = services.osm;
76242     background = rendererBackground(context);
76243     features = rendererFeatures(context);
76244     presets = presetIndex();
76245
76246     map = rendererMap(context);
76247     context.mouse = map.mouse;
76248     context.extent = map.extent;
76249     context.pan = map.pan;
76250     context.zoomIn = map.zoomIn;
76251     context.zoomOut = map.zoomOut;
76252     context.zoomInFurther = map.zoomInFurther;
76253     context.zoomOutFurther = map.zoomOutFurther;
76254     context.redrawEnable = map.redrawEnable;
76255
76256     lodash.each(services, function(service) {
76257         if (service && typeof service.init === 'function') {
76258             service.init(context);
76259         }
76260     });
76261
76262     background.init();
76263     presets.init();
76264     areaKeys = presets.areaKeys();
76265
76266
76267     return utilRebind(context, dispatch$$1, 'on');
76268 }
76269
76270 function osmWay() {
76271     if (!(this instanceof osmWay)) {
76272         return (new osmWay()).initialize(arguments);
76273     } else if (arguments.length) {
76274         this.initialize(arguments);
76275     }
76276 }
76277
76278
76279 osmEntity$$1.way = osmWay;
76280
76281 osmWay.prototype = Object.create(osmEntity$$1.prototype);
76282
76283
76284 lodash.extend(osmWay.prototype, {
76285     type: 'way',
76286     nodes: [],
76287
76288
76289     copy: function(resolver, copies) {
76290         if (copies[this.id])
76291             return copies[this.id];
76292
76293         var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
76294
76295         var nodes = this.nodes.map(function(id) {
76296             return resolver.entity(id).copy(resolver, copies).id;
76297         });
76298
76299         copy = copy.update({ nodes: nodes });
76300         copies[this.id] = copy;
76301
76302         return copy;
76303     },
76304
76305
76306     extent: function(resolver) {
76307         return resolver.transient(this, 'extent', function() {
76308             var extent$$1 = geoExtent$$1();
76309             for (var i = 0; i < this.nodes.length; i++) {
76310                 var node = resolver.hasEntity(this.nodes[i]);
76311                 if (node) {
76312                     extent$$1._extend(node.extent());
76313                 }
76314             }
76315             return extent$$1;
76316         });
76317     },
76318
76319
76320     first: function() {
76321         return this.nodes[0];
76322     },
76323
76324
76325     last: function() {
76326         return this.nodes[this.nodes.length - 1];
76327     },
76328
76329
76330     contains: function(node) {
76331         return this.nodes.indexOf(node) >= 0;
76332     },
76333
76334
76335     affix: function(node) {
76336         if (this.nodes[0] === node) return 'prefix';
76337         if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
76338     },
76339
76340
76341     layer: function() {
76342         // explicit layer tag, clamp between -10, 10..
76343         if (isFinite(this.tags.layer)) {
76344             return Math.max(-10, Math.min(+(this.tags.layer), 10));
76345         }
76346
76347         // implied layer tag..
76348         if (this.tags.location === 'overground') return 1;
76349         if (this.tags.location === 'underground') return -1;
76350         if (this.tags.location === 'underwater') return -10;
76351
76352         if (this.tags.power === 'line') return 10;
76353         if (this.tags.power === 'minor_line') return 10;
76354         if (this.tags.aerialway) return 10;
76355         if (this.tags.bridge) return 1;
76356         if (this.tags.cutting) return -1;
76357         if (this.tags.tunnel) return -1;
76358         if (this.tags.waterway) return -1;
76359         if (this.tags.man_made === 'pipeline') return -10;
76360         if (this.tags.boundary) return -10;
76361         return 0;
76362     },
76363
76364
76365     isOneWay: function() {
76366         // explicit oneway tag..
76367         if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
76368         if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
76369
76370         // implied oneway tag..
76371         for (var key in this.tags) {
76372             if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
76373                 return true;
76374         }
76375         return false;
76376     },
76377
76378
76379     lanes: function() {
76380         return osmLanes(this);
76381     },
76382
76383
76384     isClosed: function() {
76385         return this.nodes.length > 1 && this.first() === this.last();
76386     },
76387
76388
76389     isConvex: function(resolver) {
76390         if (!this.isClosed() || this.isDegenerate()) return null;
76391
76392         var nodes = lodash.uniq(resolver.childNodes(this)),
76393             coords = lodash.map(nodes, 'loc'),
76394             curr = 0, prev = 0;
76395
76396         for (var i = 0; i < coords.length; i++) {
76397             var o = coords[(i+1) % coords.length],
76398                 a = coords[i],
76399                 b = coords[(i+2) % coords.length],
76400                 res = geoCross(o, a, b);
76401
76402             curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
76403             if (curr === 0) {
76404                 continue;
76405             } else if (prev && curr !== prev) {
76406                 return false;
76407             }
76408             prev = curr;
76409         }
76410         return true;
76411     },
76412
76413
76414     isArea: function() {
76415         // `highway` and `railway` are typically linear features, but there
76416         // are a few exceptions that should be treated as areas, even in the
76417         // absence of a proper `area=yes` or `areaKeys` tag.. see #4194
76418         var lineKeys = {
76419             highway: {
76420                 rest_area: true,
76421                 services: true
76422             },
76423             railway: {
76424                 roundhouse: true,
76425                 station: true,
76426                 traverser: true,
76427                 turntable: true,
76428                 wash: true
76429             }
76430         };
76431
76432         if (this.tags.area === 'yes')
76433             return true;
76434         if (!this.isClosed() || this.tags.area === 'no')
76435             return false;
76436         for (var key in this.tags) {
76437             if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
76438                 return true;
76439             }
76440             if (key in lineKeys && this.tags[key] in lineKeys[key]) {
76441                 return true;
76442             }
76443         }
76444         return false;
76445     },
76446
76447
76448     isDegenerate: function() {
76449         return lodash.uniq(this.nodes).length < (this.isArea() ? 3 : 2);
76450     },
76451
76452
76453     areAdjacent: function(n1, n2) {
76454         for (var i = 0; i < this.nodes.length; i++) {
76455             if (this.nodes[i] === n1) {
76456                 if (this.nodes[i - 1] === n2) return true;
76457                 if (this.nodes[i + 1] === n2) return true;
76458             }
76459         }
76460         return false;
76461     },
76462
76463
76464     geometry: function(graph) {
76465         return graph.transient(this, 'geometry', function() {
76466             return this.isArea() ? 'area' : 'line';
76467         });
76468     },
76469
76470
76471     // If this way is not closed, append the beginning node to the end of the nodelist to close it.
76472     close: function() {
76473         if (this.isClosed() || !this.nodes.length) return this;
76474
76475         var nodes = this.nodes.slice();
76476         nodes = nodes.filter(noRepeatNodes);
76477         nodes.push(nodes[0]);
76478         return this.update({ nodes: nodes });
76479     },
76480
76481
76482     // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
76483     unclose: function() {
76484         if (!this.isClosed()) return this;
76485
76486         var nodes = this.nodes.slice(),
76487             connector = this.first(),
76488             i = nodes.length - 1;
76489
76490         // remove trailing connectors..
76491         while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
76492             nodes.splice(i, 1);
76493             i = nodes.length - 1;
76494         }
76495
76496         nodes = nodes.filter(noRepeatNodes);
76497         return this.update({ nodes: nodes });
76498     },
76499
76500
76501     // Adds a node (id) in front of the node which is currently at position index.
76502     // If index is undefined, the node will be added to the end of the way for linear ways,
76503     //   or just before the final connecting node for circular ways.
76504     // Consecutive duplicates are eliminated including existing ones.
76505     // Circularity is always preserved when adding a node.
76506     addNode: function(id, index) {
76507         var nodes = this.nodes.slice(),
76508             isClosed = this.isClosed(),
76509             max$$1 = isClosed ? nodes.length - 1 : nodes.length;
76510
76511         if (index === undefined) {
76512             index = max$$1;
76513         }
76514
76515         if (index < 0 || index > max$$1) {
76516             throw new RangeError('index ' + index + ' out of range 0..' + max$$1);
76517         }
76518
76519         // If this is a closed way, remove all connector nodes except the first one
76520         // (there may be duplicates) and adjust index if necessary..
76521         if (isClosed) {
76522             var connector = this.first();
76523
76524             // leading connectors..
76525             var i = 1;
76526             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
76527                 nodes.splice(i, 1);
76528                 if (index > i) index--;
76529             }
76530
76531             // trailing connectors..
76532             i = nodes.length - 1;
76533             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
76534                 nodes.splice(i, 1);
76535                 if (index > i) index--;
76536                 i = nodes.length - 1;
76537             }
76538         }
76539
76540         nodes.splice(index, 0, id);
76541         nodes = nodes.filter(noRepeatNodes);
76542
76543         // If the way was closed before, append a connector node to keep it closed..
76544         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
76545             nodes.push(nodes[0]);
76546         }
76547
76548         return this.update({ nodes: nodes });
76549     },
76550
76551
76552     // Replaces the node which is currently at position index with the given node (id).
76553     // Consecutive duplicates are eliminated including existing ones.
76554     // Circularity is preserved when updating a node.
76555     updateNode: function(id, index) {
76556         var nodes = this.nodes.slice(),
76557             isClosed = this.isClosed(),
76558             max$$1 = nodes.length - 1;
76559
76560         if (index === undefined || index < 0 || index > max$$1) {
76561             throw new RangeError('index ' + index + ' out of range 0..' + max$$1);
76562         }
76563
76564         // If this is a closed way, remove all connector nodes except the first one
76565         // (there may be duplicates) and adjust index if necessary..
76566         if (isClosed) {
76567             var connector = this.first();
76568
76569             // leading connectors..
76570             var i = 1;
76571             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
76572                 nodes.splice(i, 1);
76573                 if (index > i) index--;
76574             }
76575
76576             // trailing connectors..
76577             i = nodes.length - 1;
76578             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
76579                 nodes.splice(i, 1);
76580                 if (index === i) index = 0;  // update leading connector instead
76581                 i = nodes.length - 1;
76582             }
76583         }
76584
76585         nodes.splice(index, 1, id);
76586         nodes = nodes.filter(noRepeatNodes);
76587
76588         // If the way was closed before, append a connector node to keep it closed..
76589         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
76590             nodes.push(nodes[0]);
76591         }
76592
76593         return this.update({nodes: nodes});
76594     },
76595
76596
76597     // Replaces each occurrence of node id needle with replacement.
76598     // Consecutive duplicates are eliminated including existing ones.
76599     // Circularity is preserved.
76600     replaceNode: function(needle, replacement) {
76601         var nodes = this.nodes.slice(),
76602             isClosed = this.isClosed();
76603
76604         for (var i = 0; i < nodes.length; i++) {
76605             if (nodes[i] === needle) {
76606                 nodes[i] = replacement;
76607             }
76608         }
76609
76610         nodes = nodes.filter(noRepeatNodes);
76611
76612         // If the way was closed before, append a connector node to keep it closed..
76613         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
76614             nodes.push(nodes[0]);
76615         }
76616
76617         return this.update({nodes: nodes});
76618     },
76619
76620
76621     // Removes each occurrence of node id needle with replacement.
76622     // Consecutive duplicates are eliminated including existing ones.
76623     // Circularity is preserved.
76624     removeNode: function(id) {
76625         var nodes = this.nodes.slice(),
76626             isClosed = this.isClosed();
76627
76628         nodes = nodes
76629             .filter(function(node) { return node !== id; })
76630             .filter(noRepeatNodes);
76631
76632         // If the way was closed before, append a connector node to keep it closed..
76633         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
76634             nodes.push(nodes[0]);
76635         }
76636
76637         return this.update({nodes: nodes});
76638     },
76639
76640
76641     asJXON: function(changeset_id) {
76642         var r = {
76643             way: {
76644                 '@id': this.osmId(),
76645                 '@version': this.version || 0,
76646                 nd: lodash.map(this.nodes, function(id) {
76647                     return { keyAttributes: { ref: osmEntity$$1.id.toOSM(id) } };
76648                 }),
76649                 tag: lodash.map(this.tags, function(v, k) {
76650                     return { keyAttributes: { k: k, v: v } };
76651                 })
76652             }
76653         };
76654         if (changeset_id) {
76655             r.way['@changeset'] = changeset_id;
76656         }
76657         return r;
76658     },
76659
76660
76661     asGeoJSON: function(resolver) {
76662         return resolver.transient(this, 'GeoJSON', function() {
76663             var coordinates = lodash.map(resolver.childNodes(this), 'loc');
76664             if (this.isArea() && this.isClosed()) {
76665                 return {
76666                     type: 'Polygon',
76667                     coordinates: [coordinates]
76668                 };
76669             } else {
76670                 return {
76671                     type: 'LineString',
76672                     coordinates: coordinates
76673                 };
76674             }
76675         });
76676     },
76677
76678
76679     area: function(resolver) {
76680         return resolver.transient(this, 'area', function() {
76681             var nodes = resolver.childNodes(this);
76682
76683             var json$$1 = {
76684                 type: 'Polygon',
76685                 coordinates: [lodash.map(nodes, 'loc')]
76686             };
76687
76688             if (!this.isClosed() && nodes.length) {
76689                 json$$1.coordinates[0].push(nodes[0].loc);
76690             }
76691
76692             var area$$1 = area(json$$1);
76693
76694             // Heuristic for detecting counterclockwise winding order. Assumes
76695             // that OpenStreetMap polygons are not hemisphere-spanning.
76696             if (area$$1 > 2 * Math.PI) {
76697                 json$$1.coordinates[0] = json$$1.coordinates[0].reverse();
76698                 area$$1 = area(json$$1);
76699             }
76700
76701             return isNaN(area$$1) ? 0 : area$$1;
76702         });
76703     }
76704 });
76705
76706
76707 // Filter function to eliminate consecutive duplicates.
76708 function noRepeatNodes(node, i, arr) {
76709     return i === 0 || node !== arr[i - 1];
76710 }
76711
76712 function osmTurn(turn) {
76713     if (!(this instanceof osmTurn))
76714         return new osmTurn(turn);
76715     lodash.extend(this, turn);
76716 }
76717
76718
76719 function osmIntersection(graph, vertexId) {
76720     var vertex = graph.entity(vertexId),
76721         parentWays = graph.parentWays(vertex),
76722         coincident = [],
76723         highways = {};
76724
76725     function addHighway(way, adjacentNodeId) {
76726         if (highways[adjacentNodeId]) {
76727             coincident.push(adjacentNodeId);
76728         } else {
76729             highways[adjacentNodeId] = way;
76730         }
76731     }
76732
76733     // Pre-split ways that would need to be split in
76734     // order to add a restriction. The real split will
76735     // happen when the restriction is added.
76736     parentWays.forEach(function(way) {
76737         if (!way.tags.highway || way.isArea() || way.isDegenerate())
76738             return;
76739
76740         var isFirst = (vertexId === way.first()),
76741             isLast = (vertexId === way.last()),
76742             isAffix = (isFirst || isLast),
76743             isClosingNode = (isFirst && isLast);
76744
76745         if (isAffix && !isClosingNode) {
76746             var index = (isFirst ? 1 : way.nodes.length - 2);
76747             addHighway(way, way.nodes[index]);
76748
76749         } else {
76750             var splitIndex, wayA, wayB, indexA, indexB;
76751             if (isClosingNode) {
76752                 splitIndex = Math.ceil(way.nodes.length / 2);  // split at midpoint
76753                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
76754                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
76755                 indexA = 1;
76756                 indexB = way.nodes.length - 2;
76757             } else {
76758                 splitIndex = lodash.indexOf(way.nodes, vertex.id, 1);  // split at vertexid
76759                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
76760                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
76761                 indexA = splitIndex - 1;
76762                 indexB = splitIndex + 1;
76763             }
76764             graph = graph.replace(wayA).replace(wayB);
76765             addHighway(wayA, way.nodes[indexA]);
76766             addHighway(wayB, way.nodes[indexB]);
76767         }
76768     });
76769
76770     // remove any ways from this intersection that are coincident
76771     // (i.e. any adjacent node used by more than one intersecting way)
76772     coincident.forEach(function (n) {
76773         delete highways[n];
76774     });
76775
76776
76777     var intersection = {
76778         highways: highways,
76779         ways: lodash.values(highways),
76780         graph: graph
76781     };
76782
76783
76784     intersection.adjacentNodeId = function(fromWayId) {
76785         return lodash.find(lodash.keys(highways), function(k) {
76786             return highways[k].id === fromWayId;
76787         });
76788     };
76789
76790
76791     intersection.turns = function(fromNodeId) {
76792         var start = highways[fromNodeId];
76793         if (!start)
76794             return [];
76795
76796         if (start.first() === vertex.id && start.tags.oneway === 'yes')
76797             return [];
76798         if (start.last() === vertex.id && start.tags.oneway === '-1')
76799             return [];
76800
76801         function withRestriction(turn) {
76802             graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
76803                 if (relation.tags.type !== 'restriction')
76804                     return;
76805
76806                 var f = relation.memberByRole('from'),
76807                     t = relation.memberByRole('to'),
76808                     v = relation.memberByRole('via');
76809
76810                 if (f && f.id === turn.from.way &&
76811                     v && v.id === turn.via.node &&
76812                     t && t.id === turn.to.way) {
76813                     turn.restriction = relation.id;
76814                 } else if (/^only_/.test(relation.tags.restriction) &&
76815                     f && f.id === turn.from.way &&
76816                     v && v.id === turn.via.node &&
76817                     t && t.id !== turn.to.way) {
76818                     turn.restriction = relation.id;
76819                     turn.indirect_restriction = true;
76820                 }
76821             });
76822
76823             return osmTurn(turn);
76824         }
76825
76826
76827         var from = {
76828                 node: fromNodeId,
76829                 way: start.id.split(/-(a|b)/)[0]
76830             },
76831             via = { node: vertex.id },
76832             turns = [];
76833
76834         lodash.each(highways, function(end, adjacentNodeId) {
76835             if (end === start)
76836                 return;
76837
76838             // backward
76839             if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
76840                 turns.push(withRestriction({
76841                     from: from,
76842                     via: via,
76843                     to: {
76844                         node: adjacentNodeId,
76845                         way: end.id.split(/-(a|b)/)[0]
76846                     }
76847                 }));
76848             }
76849
76850             // forward
76851             if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
76852                 turns.push(withRestriction({
76853                     from: from,
76854                     via: via,
76855                     to: {
76856                         node: adjacentNodeId,
76857                         way: end.id.split(/-(a|b)/)[0]
76858                     }
76859                 }));
76860             }
76861
76862         });
76863
76864         // U-turn
76865         if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
76866             turns.push(withRestriction({
76867                 from: from,
76868                 via: via,
76869                 to: from,
76870                 u: true
76871             }));
76872         }
76873
76874         return turns;
76875     };
76876
76877     return intersection;
76878 }
76879
76880
76881 function osmInferRestriction(graph, from, via, to, projection) {
76882     var fromWay = graph.entity(from.way),
76883         fromNode = graph.entity(from.node),
76884         toWay = graph.entity(to.way),
76885         toNode = graph.entity(to.node),
76886         viaNode = graph.entity(via.node),
76887         fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
76888             (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
76889         toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
76890             (toWay.tags.oneway === '-1' && toWay.last() === via.node),
76891         angle = geoAngle(viaNode, fromNode, projection) -
76892                 geoAngle(viaNode, toNode, projection);
76893
76894     angle = angle * 180 / Math.PI;
76895
76896     while (angle < 0)
76897         angle += 360;
76898
76899     if (fromNode === toNode)
76900         return 'no_u_turn';
76901     if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
76902         return 'no_u_turn';
76903     if (angle < 158)
76904         return 'no_right_turn';
76905     if (angle > 202)
76906         return 'no_left_turn';
76907
76908     return 'no_straight_on';
76909 }
76910
76911 function actionAddMember(relationId, member, memberIndex) {
76912     return function(graph) {
76913         var relation = graph.entity(relationId);
76914
76915         if (isNaN(memberIndex) && member.type === 'way') {
76916             var members = relation.indexedMembers();
76917             members.push(member);
76918
76919             var joined = osmJoinWays(members, graph);
76920             for (var i = 0; i < joined.length; i++) {
76921                 var segment = joined[i];
76922                 for (var j = 0; j < segment.length && segment.length >= 2; j++) {
76923                     if (segment[j] !== member)
76924                         continue;
76925
76926                     if (j === 0) {
76927                         memberIndex = segment[j + 1].index;
76928                     } else if (j === segment.length - 1) {
76929                         memberIndex = segment[j - 1].index + 1;
76930                     } else {
76931                         memberIndex = Math.min(segment[j - 1].index + 1, segment[j + 1].index + 1);
76932                     }
76933                 }
76934             }
76935         }
76936
76937         return graph.replace(relation.addMember(member, memberIndex));
76938     };
76939 }
76940
76941 function actionAddMidpoint(midpoint, node) {
76942     return function(graph) {
76943         graph = graph.replace(node.move(midpoint.loc));
76944
76945         var parents = lodash.intersection(
76946             graph.parentWays(graph.entity(midpoint.edge[0])),
76947             graph.parentWays(graph.entity(midpoint.edge[1])));
76948
76949         parents.forEach(function(way) {
76950             for (var i = 0; i < way.nodes.length - 1; i++) {
76951                 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
76952                     graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
76953
76954                     // Add only one midpoint on doubled-back segments,
76955                     // turning them into self-intersections.
76956                     return;
76957                 }
76958             }
76959         });
76960
76961         return graph;
76962     };
76963 }
76964
76965 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
76966 function actionAddVertex(wayId, nodeId, index) {
76967     return function(graph) {
76968         return graph.replace(graph.entity(wayId).addNode(nodeId, index));
76969     };
76970 }
76971
76972 function actionChangeMember(relationId, member, memberIndex) {
76973     return function(graph) {
76974         return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
76975     };
76976 }
76977
76978 function actionChangePreset(entityId, oldPreset, newPreset) {
76979     return function(graph) {
76980         var entity = graph.entity(entityId),
76981             geometry = entity.geometry(graph),
76982             tags = entity.tags;
76983
76984         if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
76985         if (newPreset) tags = newPreset.applyTags(tags, geometry);
76986
76987         return graph.replace(entity.update({tags: tags}));
76988     };
76989 }
76990
76991 function actionChangeTags(entityId, tags) {
76992     return function(graph) {
76993         var entity = graph.entity(entityId);
76994         return graph.replace(entity.update({tags: tags}));
76995     };
76996 }
76997
76998 function actionCircularize(wayId, projection$$1, maxAngle) {
76999     maxAngle = (maxAngle || 20) * Math.PI / 180;
77000
77001
77002     var action = function(graph, t) {
77003         if (t === null || !isFinite(t)) t = 1;
77004         t = Math.min(Math.max(+t, 0), 1);
77005
77006         var way = graph.entity(wayId),
77007             origNodes = {};
77008
77009         graph.childNodes(way).forEach(function(node) {
77010             if (!origNodes[node.id]) origNodes[node.id] = node;
77011         });
77012
77013         if (!way.isConvex(graph)) {
77014             graph = action.makeConvex(graph);
77015         }
77016
77017         var nodes = lodash.uniq(graph.childNodes(way)),
77018             keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
77019             points = nodes.map(function(n) { return projection$$1(n.loc); }),
77020             keyPoints = keyNodes.map(function(n) { return projection$$1(n.loc); }),
77021             centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3polygonCentroid(points),
77022             radius = median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
77023             sign = d3polygonArea(points) > 0 ? 1 : -1,
77024             ids;
77025
77026         // we need atleast two key nodes for the algorithm to work
77027         if (!keyNodes.length) {
77028             keyNodes = [nodes[0]];
77029             keyPoints = [points[0]];
77030         }
77031
77032         if (keyNodes.length === 1) {
77033             var index = nodes.indexOf(keyNodes[0]),
77034                 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
77035
77036             keyNodes.push(nodes[oppositeIndex]);
77037             keyPoints.push(points[oppositeIndex]);
77038         }
77039
77040         // key points and nodes are those connected to the ways,
77041         // they are projected onto the circle, inbetween nodes are moved
77042         // to constant intervals between key nodes, extra inbetween nodes are
77043         // added if necessary.
77044         for (var i = 0; i < keyPoints.length; i++) {
77045             var nextKeyNodeIndex = (i + 1) % keyNodes.length,
77046                 startNode = keyNodes[i],
77047                 endNode = keyNodes[nextKeyNodeIndex],
77048                 startNodeIndex = nodes.indexOf(startNode),
77049                 endNodeIndex = nodes.indexOf(endNode),
77050                 numberNewPoints = -1,
77051                 indexRange = endNodeIndex - startNodeIndex,
77052                 nearNodes = {},
77053                 inBetweenNodes = [],
77054                 startAngle, endAngle, totalAngle, eachAngle,
77055                 angle, loc, node, origNode, j;
77056
77057             if (indexRange < 0) {
77058                 indexRange += nodes.length;
77059             }
77060
77061             // position this key node
77062             var distance$$1 = geoEuclideanDistance(centroid, keyPoints[i]);
77063             if (distance$$1 === 0) { distance$$1 = 1e-4; }
77064             keyPoints[i] = [
77065                 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance$$1 * radius,
77066                 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance$$1 * radius
77067             ];
77068             loc = projection$$1.invert(keyPoints[i]);
77069             node = keyNodes[i];
77070             origNode = origNodes[node.id];
77071             node = node.move(geoInterp(origNode.loc, loc, t));
77072             graph = graph.replace(node);
77073
77074             // figure out the between delta angle we want to match to
77075             startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
77076             endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
77077             totalAngle = endAngle - startAngle;
77078
77079             // detects looping around -pi/pi
77080             if (totalAngle * sign > 0) {
77081                 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
77082             }
77083
77084             do {
77085                 numberNewPoints++;
77086                 eachAngle = totalAngle / (indexRange + numberNewPoints);
77087             } while (Math.abs(eachAngle) > maxAngle);
77088
77089
77090             // move existing nodes
77091             for (j = 1; j < indexRange; j++) {
77092                 angle = startAngle + j * eachAngle;
77093                 loc = projection$$1.invert([
77094                     centroid[0] + Math.cos(angle) * radius,
77095                     centroid[1] + Math.sin(angle) * radius
77096                 ]);
77097
77098                 node = nodes[(j + startNodeIndex) % nodes.length];
77099                 origNode = origNodes[node.id];
77100                 nearNodes[node.id] = angle;
77101
77102                 node = node.move(geoInterp(origNode.loc, loc, t));
77103                 graph = graph.replace(node);
77104             }
77105
77106             // add new inbetween nodes if necessary
77107             for (j = 0; j < numberNewPoints; j++) {
77108                 angle = startAngle + (indexRange + j) * eachAngle;
77109                 loc = projection$$1.invert([
77110                     centroid[0] + Math.cos(angle) * radius,
77111                     centroid[1] + Math.sin(angle) * radius
77112                 ]);
77113
77114                 // choose a nearnode to use as the original
77115                 var min$$1 = Infinity;
77116                 for (var nodeId in nearNodes) {
77117                     var nearAngle = nearNodes[nodeId],
77118                         dist = Math.abs(nearAngle - angle);
77119                     if (dist < min$$1) {
77120                         dist = min$$1;
77121                         origNode = origNodes[nodeId];
77122                     }
77123                 }
77124
77125                 node = osmNode({ loc: geoInterp(origNode.loc, loc, t) });
77126                 graph = graph.replace(node);
77127
77128                 nodes.splice(endNodeIndex + j, 0, node);
77129                 inBetweenNodes.push(node.id);
77130             }
77131
77132             // Check for other ways that share these keyNodes..
77133             // If keyNodes are adjacent in both ways,
77134             // we can add inBetween nodes to that shared way too..
77135             if (indexRange === 1 && inBetweenNodes.length) {
77136                 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
77137                     endIndex1 = way.nodes.lastIndexOf(endNode.id),
77138                     wayDirection1 = (endIndex1 - startIndex1);
77139                 if (wayDirection1 < -1) { wayDirection1 = 1; }
77140
77141                 /* eslint-disable no-loop-func */
77142                 lodash.each(lodash.without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
77143                     if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
77144                         var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
77145                             endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
77146                             wayDirection2 = (endIndex2 - startIndex2),
77147                             insertAt = endIndex2;
77148                         if (wayDirection2 < -1) { wayDirection2 = 1; }
77149
77150                         if (wayDirection1 !== wayDirection2) {
77151                             inBetweenNodes.reverse();
77152                             insertAt = startIndex2;
77153                         }
77154                         for (j = 0; j < inBetweenNodes.length; j++) {
77155                             sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
77156                         }
77157                         graph = graph.replace(sharedWay);
77158                     }
77159                 });
77160                 /* eslint-enable no-loop-func */
77161             }
77162
77163         }
77164
77165         // update the way to have all the new nodes
77166         ids = nodes.map(function(n) { return n.id; });
77167         ids.push(ids[0]);
77168
77169         way = way.update({nodes: ids});
77170         graph = graph.replace(way);
77171
77172         return graph;
77173     };
77174
77175
77176     action.makeConvex = function(graph) {
77177         var way = graph.entity(wayId),
77178             nodes = lodash.uniq(graph.childNodes(way)),
77179             points = nodes.map(function(n) { return projection$$1(n.loc); }),
77180             sign = d3polygonArea(points) > 0 ? 1 : -1,
77181             hull = d3polygonHull(points);
77182
77183         // D3 convex hulls go counterclockwise..
77184         if (sign === -1) {
77185             nodes.reverse();
77186             points.reverse();
77187         }
77188
77189         for (var i = 0; i < hull.length - 1; i++) {
77190             var startIndex = points.indexOf(hull[i]),
77191                 endIndex = points.indexOf(hull[i+1]),
77192                 indexRange = (endIndex - startIndex);
77193
77194             if (indexRange < 0) {
77195                 indexRange += nodes.length;
77196             }
77197
77198             // move interior nodes to the surface of the convex hull..
77199             for (var j = 1; j < indexRange; j++) {
77200                 var point = geoInterp(hull[i], hull[i+1], j / indexRange),
77201                     node = nodes[(j + startIndex) % nodes.length].move(projection$$1.invert(point));
77202                 graph = graph.replace(node);
77203             }
77204         }
77205         return graph;
77206     };
77207
77208
77209     action.disabled = function(graph) {
77210         if (!graph.entity(wayId).isClosed())
77211             return 'not_closed';
77212     };
77213
77214
77215     action.transitionable = true;
77216
77217
77218     return action;
77219 }
77220
77221 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
77222 function actionDeleteWay(wayId) {
77223
77224
77225     function canDeleteNode(node, graph) {
77226         return !graph.parentWays(node).length &&
77227             !graph.parentRelations(node).length &&
77228             !node.hasInterestingTags();
77229     }
77230
77231
77232     var action = function(graph) {
77233         var way = graph.entity(wayId);
77234
77235         graph.parentRelations(way)
77236             .forEach(function(parent) {
77237                 parent = parent.removeMembersWithID(wayId);
77238                 graph = graph.replace(parent);
77239
77240                 if (parent.isDegenerate()) {
77241                     graph = actionDeleteRelation(parent.id)(graph);
77242                 }
77243             });
77244
77245         lodash.uniq(way.nodes).forEach(function(nodeId) {
77246             graph = graph.replace(way.removeNode(nodeId));
77247
77248             var node = graph.entity(nodeId);
77249             if (canDeleteNode(node, graph)) {
77250                 graph = graph.remove(node);
77251             }
77252         });
77253
77254         return graph.remove(way);
77255     };
77256
77257
77258     return action;
77259 }
77260
77261 function actionDeleteMultiple(ids) {
77262     var actions = {
77263         way: actionDeleteWay,
77264         node: actionDeleteNode,
77265         relation: actionDeleteRelation
77266     };
77267
77268
77269     var action = function(graph) {
77270         ids.forEach(function(id) {
77271             if (graph.hasEntity(id)) { // It may have been deleted aready.
77272                 graph = actions[graph.entity(id).type](id)(graph);
77273             }
77274         });
77275
77276         return graph;
77277     };
77278
77279
77280     return action;
77281 }
77282
77283 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
77284 function actionDeleteRelation(relationId) {
77285
77286
77287     function canDeleteEntity(entity, graph) {
77288         return !graph.parentWays(entity).length &&
77289             !graph.parentRelations(entity).length &&
77290             !entity.hasInterestingTags();
77291     }
77292
77293
77294     var action = function(graph) {
77295         var relation = graph.entity(relationId);
77296
77297         graph.parentRelations(relation)
77298             .forEach(function(parent) {
77299                 parent = parent.removeMembersWithID(relationId);
77300                 graph = graph.replace(parent);
77301
77302                 if (parent.isDegenerate()) {
77303                     graph = actionDeleteRelation(parent.id)(graph);
77304                 }
77305             });
77306
77307         lodash.uniq(lodash.map(relation.members, 'id')).forEach(function(memberId) {
77308             graph = graph.replace(relation.removeMembersWithID(memberId));
77309
77310             var entity = graph.entity(memberId);
77311             if (canDeleteEntity(entity, graph)) {
77312                 graph = actionDeleteMultiple([memberId])(graph);
77313             }
77314         });
77315
77316         return graph.remove(relation);
77317     };
77318
77319
77320     return action;
77321 }
77322
77323 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
77324 function actionDeleteNode(nodeId) {
77325     var action = function(graph) {
77326         var node = graph.entity(nodeId);
77327
77328         graph.parentWays(node)
77329             .forEach(function(parent) {
77330                 parent = parent.removeNode(nodeId);
77331                 graph = graph.replace(parent);
77332
77333                 if (parent.isDegenerate()) {
77334                     graph = actionDeleteWay(parent.id)(graph);
77335                 }
77336             });
77337
77338         graph.parentRelations(node)
77339             .forEach(function(parent) {
77340                 parent = parent.removeMembersWithID(nodeId);
77341                 graph = graph.replace(parent);
77342
77343                 if (parent.isDegenerate()) {
77344                     graph = actionDeleteRelation(parent.id)(graph);
77345                 }
77346             });
77347
77348         return graph.remove(node);
77349     };
77350
77351
77352     return action;
77353 }
77354
77355 // Connect the ways at the given nodes.
77356 //
77357 // The last node will survive. All other nodes will be replaced with
77358 // the surviving node in parent ways, and then removed.
77359 //
77360 // Tags and relation memberships of of non-surviving nodes are merged
77361 // to the survivor.
77362 //
77363 // This is the inverse of `iD.actionDisconnect`.
77364 //
77365 // Reference:
77366 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
77367 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
77368 //
77369 function actionConnect(nodeIds) {
77370     return function(graph) {
77371         var survivor = graph.entity(lodash.last(nodeIds));
77372
77373         for (var i = 0; i < nodeIds.length - 1; i++) {
77374             var node = graph.entity(nodeIds[i]);
77375
77376             /* eslint-disable no-loop-func */
77377             graph.parentWays(node).forEach(function(parent) {
77378                 if (!parent.areAdjacent(node.id, survivor.id)) {
77379                     graph = graph.replace(parent.replaceNode(node.id, survivor.id));
77380                 }
77381             });
77382
77383             graph.parentRelations(node).forEach(function(parent) {
77384                 graph = graph.replace(parent.replaceMember(node, survivor));
77385             });
77386             /* eslint-enable no-loop-func */
77387
77388             survivor = survivor.mergeTags(node.tags);
77389             graph = actionDeleteNode(node.id)(graph);
77390         }
77391
77392         graph = graph.replace(survivor);
77393
77394         return graph;
77395     };
77396 }
77397
77398 function actionCopyEntities(ids, fromGraph) {
77399     var copies = {};
77400
77401
77402     var action = function(graph) {
77403         ids.forEach(function(id) {
77404             fromGraph.entity(id).copy(fromGraph, copies);
77405         });
77406
77407         for (var id in copies) {
77408             graph = graph.replace(copies[id]);
77409         }
77410
77411         return graph;
77412     };
77413
77414
77415     action.copies = function() {
77416         return copies;
77417     };
77418
77419
77420     return action;
77421 }
77422
77423 function actionDeleteMember(relationId, memberIndex) {
77424     return function(graph) {
77425         var relation = graph.entity(relationId)
77426             .removeMember(memberIndex);
77427
77428         graph = graph.replace(relation);
77429
77430         if (relation.isDegenerate())
77431             graph = actionDeleteRelation(relation.id)(graph);
77432
77433         return graph;
77434     };
77435 }
77436
77437 function actionDeprecateTags(entityId) {
77438
77439     return function(graph) {
77440         var entity = graph.entity(entityId),
77441             newtags = lodash.clone(entity.tags),
77442             change = false,
77443             rule;
77444
77445         // This handles dataDeprecated tags with a single condition
77446         for (var i = 0; i < dataDeprecated.length; i++) {
77447
77448             rule = dataDeprecated[i];
77449             var match = lodash.toPairs(rule.old)[0],
77450                 replacements = rule.replace ? lodash.toPairs(rule.replace) : null;
77451
77452             if (entity.tags[match[0]] && match[1] === '*') {
77453
77454                 var value = entity.tags[match[0]];
77455                 if (replacements && !newtags[replacements[0][0]]) {
77456                     newtags[replacements[0][0]] = value;
77457                 }
77458                 delete newtags[match[0]];
77459                 change = true;
77460
77461             } else if (entity.tags[match[0]] === match[1]) {
77462                 newtags = lodash.assign({}, rule.replace || {}, lodash.omit(newtags, match[0]));
77463                 change = true;
77464             }
77465         }
77466
77467         if (change) {
77468             return graph.replace(entity.update({tags: newtags}));
77469         } else {
77470             return graph;
77471         }
77472     };
77473 }
77474
77475 function actionDiscardTags(difference) {
77476
77477     return function(graph) {
77478         function discardTags(entity) {
77479             if (!lodash.isEmpty(entity.tags)) {
77480                 var tags = {};
77481                 lodash.each(entity.tags, function(v, k) {
77482                     if (v) tags[k] = v;
77483                 });
77484
77485                 graph = graph.replace(entity.update({
77486                     tags: lodash.omit(tags, dataDiscarded)
77487                 }));
77488             }
77489         }
77490
77491         difference.modified().forEach(discardTags);
77492         difference.created().forEach(discardTags);
77493
77494         return graph;
77495     };
77496 }
77497
77498 // Disconect the ways at the given node.
77499 //
77500 // Optionally, disconnect only the given ways.
77501 //
77502 // For testing convenience, accepts an ID to assign to the (first) new node.
77503 // Normally, this will be undefined and the way will automatically
77504 // be assigned a new ID.
77505 //
77506 // This is the inverse of `iD.actionConnect`.
77507 //
77508 // Reference:
77509 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
77510 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
77511 //
77512 function actionDisconnect(nodeId, newNodeId) {
77513     var wayIds;
77514
77515
77516     var action = function(graph) {
77517         var node = graph.entity(nodeId),
77518             connections = action.connections(graph);
77519
77520         connections.forEach(function(connection) {
77521             var way = graph.entity(connection.wayID),
77522                 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
77523
77524             graph = graph.replace(newNode);
77525             if (connection.index === 0 && way.isArea()) {
77526                 // replace shared node with shared node..
77527                 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
77528             } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
77529                 // replace closing node with new new node..
77530                 graph = graph.replace(way.unclose().addNode(newNode.id));
77531             } else {
77532                 // replace shared node with multiple new nodes..
77533                 graph = graph.replace(way.updateNode(newNode.id, connection.index));
77534             }
77535         });
77536
77537         return graph;
77538     };
77539
77540
77541     action.connections = function(graph) {
77542         var candidates = [],
77543             keeping = false,
77544             parentWays = graph.parentWays(graph.entity(nodeId));
77545
77546         parentWays.forEach(function(way) {
77547             if (wayIds && wayIds.indexOf(way.id) === -1) {
77548                 keeping = true;
77549                 return;
77550             }
77551             if (way.isArea() && (way.nodes[0] === nodeId)) {
77552                 candidates.push({ wayID: way.id, index: 0 });
77553             } else {
77554                 way.nodes.forEach(function(waynode, index) {
77555                     if (waynode === nodeId) {
77556                         candidates.push({ wayID: way.id, index: index });
77557                     }
77558                 });
77559             }
77560         });
77561
77562         return keeping ? candidates : candidates.slice(1);
77563     };
77564
77565
77566     action.disabled = function(graph) {
77567         var connections = action.connections(graph);
77568         if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
77569             return 'not_connected';
77570
77571         var parentWays = graph.parentWays(graph.entity(nodeId)),
77572             seenRelationIds = {},
77573             sharedRelation;
77574
77575         parentWays.forEach(function(way) {
77576             if (wayIds && wayIds.indexOf(way.id) === -1)
77577                 return;
77578
77579             var relations = graph.parentRelations(way);
77580             relations.forEach(function(relation) {
77581                 if (relation.id in seenRelationIds) {
77582                     sharedRelation = relation;
77583                 } else {
77584                     seenRelationIds[relation.id] = true;
77585                 }
77586             });
77587         });
77588
77589         if (sharedRelation)
77590             return 'relation';
77591     };
77592
77593
77594     action.limitWays = function(_) {
77595         if (!arguments.length) return wayIds;
77596         wayIds = _;
77597         return action;
77598     };
77599
77600
77601     return action;
77602 }
77603
77604 // Join ways at the end node they share.
77605 //
77606 // This is the inverse of `iD.actionSplit`.
77607 //
77608 // Reference:
77609 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
77610 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
77611 //
77612 function actionJoin(ids) {
77613
77614     function groupEntitiesByGeometry(graph) {
77615         var entities = ids.map(function(id) { return graph.entity(id); });
77616         return lodash.extend({line: []}, lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
77617     }
77618
77619
77620     var action = function(graph) {
77621         var ways = ids.map(graph.entity, graph),
77622             survivor = ways[0];
77623
77624         // Prefer to keep an existing way.
77625         for (var i = 0; i < ways.length; i++) {
77626             if (!ways[i].isNew()) {
77627                 survivor = ways[i];
77628                 break;
77629             }
77630         }
77631
77632         var joined = osmJoinWays(ways, graph)[0];
77633
77634         survivor = survivor.update({nodes: lodash.map(joined.nodes, 'id')});
77635         graph = graph.replace(survivor);
77636
77637         joined.forEach(function(way) {
77638             if (way.id === survivor.id)
77639                 return;
77640
77641             graph.parentRelations(way).forEach(function(parent) {
77642                 graph = graph.replace(parent.replaceMember(way, survivor));
77643             });
77644
77645             survivor = survivor.mergeTags(way.tags);
77646
77647             graph = graph.replace(survivor);
77648             graph = actionDeleteWay(way.id)(graph);
77649         });
77650
77651         return graph;
77652     };
77653
77654
77655     action.disabled = function(graph) {
77656         var geometries = groupEntitiesByGeometry(graph);
77657         if (ids.length < 2 || ids.length !== geometries.line.length)
77658             return 'not_eligible';
77659
77660         var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
77661         if (joined.length > 1)
77662             return 'not_adjacent';
77663
77664         var nodeIds = lodash.map(joined[0].nodes, 'id').slice(1, -1),
77665             relation,
77666             tags = {},
77667             conflicting = false;
77668
77669         joined[0].forEach(function(way) {
77670             var parents = graph.parentRelations(way);
77671             parents.forEach(function(parent) {
77672                 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
77673                     relation = parent;
77674             });
77675
77676             for (var k in way.tags) {
77677                 if (!(k in tags)) {
77678                     tags[k] = way.tags[k];
77679                 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
77680                     conflicting = true;
77681                 }
77682             }
77683         });
77684
77685         if (relation)
77686             return 'restriction';
77687
77688         if (conflicting)
77689             return 'conflicting_tags';
77690     };
77691
77692
77693     return action;
77694 }
77695
77696 function actionMerge(ids) {
77697
77698     function groupEntitiesByGeometry(graph) {
77699         var entities = ids.map(function(id) { return graph.entity(id); });
77700         return lodash.extend({point: [], area: [], line: [], relation: []},
77701             lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
77702     }
77703
77704
77705     var action = function(graph) {
77706         var geometries = groupEntitiesByGeometry(graph),
77707             target = geometries.area[0] || geometries.line[0],
77708             points = geometries.point;
77709
77710         points.forEach(function(point) {
77711             target = target.mergeTags(point.tags);
77712             graph = graph.replace(target);
77713
77714             graph.parentRelations(point).forEach(function(parent) {
77715                 graph = graph.replace(parent.replaceMember(point, target));
77716             });
77717
77718             var nodes = lodash.uniq(graph.childNodes(target)),
77719                 removeNode = point;
77720
77721             for (var i = 0; i < nodes.length; i++) {
77722                 var node = nodes[i];
77723                 if (graph.parentWays(node).length > 1 ||
77724                     graph.parentRelations(node).length ||
77725                     node.hasInterestingTags()) {
77726                     continue;
77727                 }
77728
77729                 // Found an uninteresting child node on the target way.
77730                 // Move orig point into its place to preserve point's history. #3683
77731                 graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
77732                 target = target.replaceNode(node.id, point.id);
77733                 graph = graph.replace(target);
77734                 removeNode = node;
77735                 break;
77736             }
77737
77738             graph = graph.remove(removeNode);
77739         });
77740
77741         return graph;
77742     };
77743
77744
77745     action.disabled = function(graph) {
77746         var geometries = groupEntitiesByGeometry(graph);
77747         if (geometries.point.length === 0 ||
77748             (geometries.area.length + geometries.line.length) !== 1 ||
77749             geometries.relation.length !== 0)
77750             return 'not_eligible';
77751     };
77752
77753
77754     return action;
77755 }
77756
77757 function actionMergePolygon(ids, newRelationId) {
77758
77759     function groupEntities(graph) {
77760         var entities = ids.map(function (id) { return graph.entity(id); });
77761         return lodash.extend({
77762                 closedWay: [],
77763                 multipolygon: [],
77764                 other: []
77765             }, lodash.groupBy(entities, function(entity) {
77766                 if (entity.type === 'way' && entity.isClosed()) {
77767                     return 'closedWay';
77768                 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
77769                     return 'multipolygon';
77770                 } else {
77771                     return 'other';
77772                 }
77773             }));
77774     }
77775
77776
77777     var action = function(graph) {
77778         var entities = groupEntities(graph);
77779
77780         // An array representing all the polygons that are part of the multipolygon.
77781         //
77782         // Each element is itself an array of objects with an id property, and has a
77783         // locs property which is an array of the locations forming the polygon.
77784         var polygons = entities.multipolygon.reduce(function(polygons, m) {
77785             return polygons.concat(osmJoinWays(m.members, graph));
77786         }, []).concat(entities.closedWay.map(function(d) {
77787             var member = [{id: d.id}];
77788             member.nodes = graph.childNodes(d);
77789             return member;
77790         }));
77791
77792         // contained is an array of arrays of boolean values,
77793         // where contained[j][k] is true iff the jth way is
77794         // contained by the kth way.
77795         var contained = polygons.map(function(w, i) {
77796             return polygons.map(function(d, n) {
77797                 if (i === n) return null;
77798                 return geoPolygonContainsPolygon(
77799                     lodash.map(d.nodes, 'loc'),
77800                     lodash.map(w.nodes, 'loc'));
77801             });
77802         });
77803
77804         // Sort all polygons as either outer or inner ways
77805         var members = [],
77806             outer = true;
77807
77808         while (polygons.length) {
77809             extractUncontained(polygons);
77810             polygons = polygons.filter(isContained);
77811             contained = contained.filter(isContained).map(filterContained);
77812         }
77813
77814         function isContained(d, i) {
77815             return lodash.some(contained[i]);
77816         }
77817
77818         function filterContained(d) {
77819             return d.filter(isContained);
77820         }
77821
77822         function extractUncontained(polygons) {
77823             polygons.forEach(function(d, i) {
77824                 if (!isContained(d, i)) {
77825                     d.forEach(function(member) {
77826                         members.push({
77827                             type: 'way',
77828                             id: member.id,
77829                             role: outer ? 'outer' : 'inner'
77830                         });
77831                     });
77832                 }
77833             });
77834             outer = !outer;
77835         }
77836
77837         // Move all tags to one relation
77838         var relation = entities.multipolygon[0] ||
77839             osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
77840
77841         entities.multipolygon.slice(1).forEach(function(m) {
77842             relation = relation.mergeTags(m.tags);
77843             graph = graph.remove(m);
77844         });
77845
77846         entities.closedWay.forEach(function(way) {
77847             function isThisOuter(m) {
77848                 return m.id === way.id && m.role !== 'inner';
77849             }
77850             if (members.some(isThisOuter)) {
77851                 relation = relation.mergeTags(way.tags);
77852                 graph = graph.replace(way.update({ tags: {} }));
77853             }
77854         });
77855
77856         return graph.replace(relation.update({
77857             members: members,
77858             tags: lodash.omit(relation.tags, 'area')
77859         }));
77860     };
77861
77862
77863     action.disabled = function(graph) {
77864         var entities = groupEntities(graph);
77865         if (entities.other.length > 0 ||
77866             entities.closedWay.length + entities.multipolygon.length < 2)
77867             return 'not_eligible';
77868         if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
77869             return 'incomplete_relation';
77870     };
77871
77872
77873     return action;
77874 }
77875
77876 // Copyright (c) 2006, 2008 Tony Garnock-Jones <tonyg@lshift.net>
77877 // Copyright (c) 2006, 2008 LShift Ltd. <query@lshift.net>
77878 //
77879 // Permission is hereby granted, free of charge, to any person
77880 // obtaining a copy of this software and associated documentation files
77881 // (the "Software"), to deal in the Software without restriction,
77882 // including without limitation the rights to use, copy, modify, merge,
77883 // publish, distribute, sublicense, and/or sell copies of the Software,
77884 // and to permit persons to whom the Software is furnished to do so,
77885 // subject to the following conditions:
77886 //
77887 // The above copyright notice and this permission notice shall be
77888 // included in all copies or substantial portions of the Software.
77889 //
77890 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
77891 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
77892 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
77893 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
77894 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
77895 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
77896 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
77897 // SOFTWARE.
77898
77899 // source:  https://bitbucket.org/lshift/synchrotron/src
77900 function longest_common_subsequence(file1, file2) {
77901     /* Text diff algorithm following Hunt and McIlroy 1976.
77902      * J. W. Hunt and M. D. McIlroy, An algorithm for differential file
77903      * comparison, Bell Telephone Laboratories CSTR #41 (1976)
77904      * http://www.cs.dartmouth.edu/~doug/
77905      *
77906      * Expects two arrays of strings.
77907      */
77908     var equivalenceClasses;
77909     var file2indices;
77910     var newCandidate;
77911     var candidates;
77912     var line;
77913     var c, i, j, jX, r, s;
77914
77915     equivalenceClasses = {};
77916     for (j = 0; j < file2.length; j++) {
77917         line = file2[j];
77918         if (equivalenceClasses[line]) {
77919             equivalenceClasses[line].push(j);
77920         } else {
77921             equivalenceClasses[line] = [j];
77922         }
77923     }
77924
77925     candidates = [{file1index: -1,
77926                    file2index: -1,
77927                    chain: null}];
77928
77929     for (i = 0; i < file1.length; i++) {
77930         line = file1[i];
77931         file2indices = equivalenceClasses[line] || [];
77932
77933         r = 0;
77934         c = candidates[0];
77935
77936         for (jX = 0; jX < file2indices.length; jX++) {
77937             j = file2indices[jX];
77938
77939             for (s = 0; s < candidates.length; s++) {
77940                 if ((candidates[s].file2index < j) &&
77941                     ((s === candidates.length - 1) ||
77942                      (candidates[s + 1].file2index > j)))
77943                     break;
77944             }
77945
77946             if (s < candidates.length) {
77947                 newCandidate = {file1index: i,
77948                                 file2index: j,
77949                                 chain: candidates[s]};
77950                 if (r === candidates.length) {
77951                     candidates.push(c);
77952                 } else {
77953                     candidates[r] = c;
77954                 }
77955                 r = s + 1;
77956                 c = newCandidate;
77957                 if (r === candidates.length) {
77958                     break; // no point in examining further (j)s
77959                 }
77960             }
77961         }
77962
77963         candidates[r] = c;
77964     }
77965
77966     // At this point, we know the LCS: it's in the reverse of the
77967     // linked-list through .chain of
77968     // candidates[candidates.length - 1].
77969
77970     return candidates[candidates.length - 1];
77971 }
77972
77973
77974
77975
77976
77977
77978
77979
77980
77981
77982
77983 function diff_indices(file1, file2) {
77984     // We apply the LCS to give a simple representation of the
77985     // offsets and lengths of mismatched chunks in the input
77986     // files. This is used by diff3_merge_indices below.
77987
77988     var result = [];
77989     var tail1 = file1.length;
77990     var tail2 = file2.length;
77991
77992     for (var candidate = longest_common_subsequence(file1, file2);
77993          candidate !== null;
77994          candidate = candidate.chain)
77995     {
77996         var mismatchLength1 = tail1 - candidate.file1index - 1;
77997         var mismatchLength2 = tail2 - candidate.file2index - 1;
77998         tail1 = candidate.file1index;
77999         tail2 = candidate.file2index;
78000
78001         if (mismatchLength1 || mismatchLength2) {
78002             result.push({file1: [tail1 + 1, mismatchLength1],
78003                          file2: [tail2 + 1, mismatchLength2]});
78004         }
78005     }
78006
78007     result.reverse();
78008     return result;
78009 }
78010
78011 function diff3_merge_indices (a, o, b) {
78012     // Given three files, A, O, and B, where both A and B are
78013     // independently derived from O, returns a fairly complicated
78014     // internal representation of merge decisions it's taken. The
78015     // interested reader may wish to consult
78016     //
78017     // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. "A
78018     // Formal Investigation of Diff3." In Arvind and Prasad,
78019     // editors, Foundations of Software Technology and Theoretical
78020     // Computer Science (FSTTCS), December 2007.
78021     //
78022     // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
78023     var i;
78024
78025     var m1 = diff_indices(o, a);
78026     var m2 = diff_indices(o, b);
78027
78028     var hunks = [];
78029     function addHunk(h, side) {
78030         hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
78031     }
78032     for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
78033     for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
78034     hunks.sort();
78035
78036     var result = [];
78037     var commonOffset = 0;
78038     function copyCommon(targetOffset) {
78039         if (targetOffset > commonOffset) {
78040             result.push([1, commonOffset, targetOffset - commonOffset]);
78041             commonOffset = targetOffset;
78042         }
78043     }
78044
78045     for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
78046         var firstHunkIndex = hunkIndex;
78047         var hunk = hunks[hunkIndex];
78048         var regionLhs = hunk[0];
78049         var regionRhs = regionLhs + hunk[2];
78050         while (hunkIndex < hunks.length - 1) {
78051             var maybeOverlapping = hunks[hunkIndex + 1];
78052             var maybeLhs = maybeOverlapping[0];
78053             if (maybeLhs > regionRhs) break;
78054             regionRhs = maybeLhs + maybeOverlapping[2];
78055             hunkIndex++;
78056         }
78057
78058         copyCommon(regionLhs);
78059         if (firstHunkIndex === hunkIndex) {
78060     // The "overlap" was only one hunk long, meaning that
78061     // there's no conflict here. Either a and o were the
78062     // same, or b and o were the same.
78063             if (hunk[4] > 0) {
78064                 result.push([hunk[1], hunk[3], hunk[4]]);
78065             }
78066         } else {
78067     // A proper conflict. Determine the extents of the
78068     // regions involved from a, o and b. Effectively merge
78069     // all the hunks on the left into one giant hunk, and
78070     // do the same for the right; then, correct for skew
78071     // in the regions of o that each side changed, and
78072     // report appropriate spans for the three sides.
78073     var regions = {
78074         0: [a.length, -1, o.length, -1],
78075         2: [b.length, -1, o.length, -1]
78076     };
78077             for (i = firstHunkIndex; i <= hunkIndex; i++) {
78078         hunk = hunks[i];
78079                 var side = hunk[1];
78080         var r = regions[side];
78081         var oLhs = hunk[0];
78082         var oRhs = oLhs + hunk[2];
78083                 var abLhs = hunk[3];
78084                 var abRhs = abLhs + hunk[4];
78085         r[0] = Math.min(abLhs, r[0]);
78086         r[1] = Math.max(abRhs, r[1]);
78087         r[2] = Math.min(oLhs, r[2]);
78088         r[3] = Math.max(oRhs, r[3]);
78089             }
78090     var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
78091     var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
78092     var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
78093     var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
78094             result.push([-1,
78095              aLhs,      aRhs      - aLhs,
78096              regionLhs, regionRhs - regionLhs,
78097              bLhs,      bRhs      - bLhs]);
78098         }
78099         commonOffset = regionRhs;
78100     }
78101
78102     copyCommon(o.length);
78103     return result;
78104 }
78105
78106 function diff3_merge (a, o, b, excludeFalseConflicts) {
78107     // Applies the output of Diff3.diff3_merge_indices to actually
78108     // construct the merged file; the returned result alternates
78109     // between "ok" and "conflict" blocks.
78110
78111     var result = [];
78112     var files = [a, o, b];
78113     var indices = diff3_merge_indices(a, o, b);
78114
78115     var okLines = [];
78116     function flushOk() {
78117         if (okLines.length) {
78118             result.push({ok: okLines});
78119         }
78120         okLines = [];
78121     }
78122     function pushOk(xs) {
78123         for (var j = 0; j < xs.length; j++) {
78124             okLines.push(xs[j]);
78125         }
78126     }
78127
78128     function isTrueConflict(rec) {
78129         if (rec[2] !== rec[6]) return true;
78130         var aoff = rec[1];
78131         var boff = rec[5];
78132         for (var j = 0; j < rec[2]; j++) {
78133             if (a[j + aoff] !== b[j + boff]) return true;
78134         }
78135         return false;
78136     }
78137
78138     for (var i = 0; i < indices.length; i++) {
78139         var x = indices[i];
78140         var side = x[0];
78141         if (side === -1) {
78142             if (excludeFalseConflicts && !isTrueConflict(x)) {
78143                 pushOk(files[0].slice(x[1], x[1] + x[2]));
78144             } else {
78145                 flushOk();
78146                 result.push({conflict: {a: a.slice(x[1], x[1] + x[2]),
78147                                         aIndex: x[1],
78148                                         o: o.slice(x[3], x[3] + x[4]),
78149                                         oIndex: x[3],
78150                                         b: b.slice(x[5], x[5] + x[6]),
78151                                         bIndex: x[5]}});
78152             }
78153         } else {
78154             pushOk(files[side].slice(x[1], x[1] + x[2]));
78155         }
78156     }
78157
78158     flushOk();
78159     return result;
78160 }
78161
78162 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
78163     var option = 'safe',  // 'safe', 'force_local', 'force_remote'
78164         conflicts = [];
78165
78166
78167     function user(d) {
78168         return lodash.isFunction(formatUser) ? formatUser(d) : d;
78169     }
78170
78171
78172     function mergeLocation(remote, target) {
78173         function pointEqual(a, b) {
78174             var epsilon = 1e-6;
78175             return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
78176         }
78177
78178         if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
78179             return target;
78180         }
78181         if (option === 'force_remote') {
78182             return target.update({loc: remote.loc});
78183         }
78184
78185         conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
78186         return target;
78187     }
78188
78189
78190     function mergeNodes(base, remote, target) {
78191         if (option === 'force_local' || lodash.isEqual(target.nodes, remote.nodes)) {
78192             return target;
78193         }
78194         if (option === 'force_remote') {
78195             return target.update({nodes: remote.nodes});
78196         }
78197
78198         var ccount = conflicts.length,
78199             o = base.nodes || [],
78200             a = target.nodes || [],
78201             b = remote.nodes || [],
78202             nodes = [],
78203             hunks = diff3_merge(a, o, b, true);
78204
78205         for (var i = 0; i < hunks.length; i++) {
78206             var hunk = hunks[i];
78207             if (hunk.ok) {
78208                 nodes.push.apply(nodes, hunk.ok);
78209             } else {
78210                 // for all conflicts, we can assume c.a !== c.b
78211                 // because `diff3_merge` called with `true` option to exclude false conflicts..
78212                 var c = hunk.conflict;
78213                 if (lodash.isEqual(c.o, c.a)) {  // only changed remotely
78214                     nodes.push.apply(nodes, c.b);
78215                 } else if (lodash.isEqual(c.o, c.b)) {  // only changed locally
78216                     nodes.push.apply(nodes, c.a);
78217                 } else {       // changed both locally and remotely
78218                     conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
78219                     break;
78220                 }
78221             }
78222         }
78223
78224         return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
78225     }
78226
78227
78228     function mergeChildren(targetWay, children, updates, graph) {
78229         function isUsed(node, targetWay) {
78230             var parentWays = lodash.map(graph.parentWays(node), 'id');
78231             return node.hasInterestingTags() ||
78232                 lodash.without(parentWays, targetWay.id).length > 0 ||
78233                 graph.parentRelations(node).length > 0;
78234         }
78235
78236         var ccount = conflicts.length;
78237
78238         for (var i = 0; i < children.length; i++) {
78239             var id = children[i],
78240                 node = graph.hasEntity(id);
78241
78242             // remove unused childNodes..
78243             if (targetWay.nodes.indexOf(id) === -1) {
78244                 if (node && !isUsed(node, targetWay)) {
78245                     updates.removeIds.push(id);
78246                 }
78247                 continue;
78248             }
78249
78250             // restore used childNodes..
78251             var local = localGraph.hasEntity(id),
78252                 remote = remoteGraph.hasEntity(id),
78253                 target;
78254
78255             if (option === 'force_remote' && remote && remote.visible) {
78256                 updates.replacements.push(remote);
78257
78258             } else if (option === 'force_local' && local) {
78259                 target = osmEntity$$1(local);
78260                 if (remote) {
78261                     target = target.update({ version: remote.version });
78262                 }
78263                 updates.replacements.push(target);
78264
78265             } else if (option === 'safe' && local && remote && local.version !== remote.version) {
78266                 target = osmEntity$$1(local, { version: remote.version });
78267                 if (remote.visible) {
78268                     target = mergeLocation(remote, target);
78269                 } else {
78270                     conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
78271                 }
78272
78273                 if (conflicts.length !== ccount) break;
78274                 updates.replacements.push(target);
78275             }
78276         }
78277
78278         return targetWay;
78279     }
78280
78281
78282     function updateChildren(updates, graph) {
78283         for (var i = 0; i < updates.replacements.length; i++) {
78284             graph = graph.replace(updates.replacements[i]);
78285         }
78286         if (updates.removeIds.length) {
78287             graph = actionDeleteMultiple(updates.removeIds)(graph);
78288         }
78289         return graph;
78290     }
78291
78292
78293     function mergeMembers(remote, target) {
78294         if (option === 'force_local' || lodash.isEqual(target.members, remote.members)) {
78295             return target;
78296         }
78297         if (option === 'force_remote') {
78298             return target.update({members: remote.members});
78299         }
78300
78301         conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
78302         return target;
78303     }
78304
78305
78306     function mergeTags(base, remote, target) {
78307         function ignoreKey(k) {
78308             return lodash.includes(dataDiscarded, k);
78309         }
78310
78311         if (option === 'force_local' || lodash.isEqual(target.tags, remote.tags)) {
78312             return target;
78313         }
78314         if (option === 'force_remote') {
78315             return target.update({tags: remote.tags});
78316         }
78317
78318         var ccount = conflicts.length,
78319             o = base.tags || {},
78320             a = target.tags || {},
78321             b = remote.tags || {},
78322             keys = lodash.reject(lodash.union(lodash.keys(o), lodash.keys(a), lodash.keys(b)), ignoreKey),
78323             tags = lodash.clone(a),
78324             changed = false;
78325
78326         for (var i = 0; i < keys.length; i++) {
78327             var k = keys[i];
78328
78329             if (o[k] !== b[k] && a[k] !== b[k]) {    // changed remotely..
78330                 if (o[k] !== a[k]) {      // changed locally..
78331                     conflicts.push(t('merge_remote_changes.conflict.tags',
78332                         { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
78333
78334                 } else {                  // unchanged locally, accept remote change..
78335                     if (b.hasOwnProperty(k)) {
78336                         tags[k] = b[k];
78337                     } else {
78338                         delete tags[k];
78339                     }
78340                     changed = true;
78341                 }
78342             }
78343         }
78344
78345         return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
78346     }
78347
78348
78349     //  `graph.base()` is the common ancestor of the two graphs.
78350     //  `localGraph` contains user's edits up to saving
78351     //  `remoteGraph` contains remote edits to modified nodes
78352     //  `graph` must be a descendent of `localGraph` and may include
78353     //      some conflict resolution actions performed on it.
78354     //
78355     //                  --- ... --- `localGraph` -- ... -- `graph`
78356     //                 /
78357     //  `graph.base()` --- ... --- `remoteGraph`
78358     //
78359     var action = function(graph) {
78360         var updates = { replacements: [], removeIds: [] },
78361             base = graph.base().entities[id],
78362             local = localGraph.entity(id),
78363             remote = remoteGraph.entity(id),
78364             target = osmEntity$$1(local, { version: remote.version });
78365
78366         // delete/undelete
78367         if (!remote.visible) {
78368             if (option === 'force_remote') {
78369                 return actionDeleteMultiple([id])(graph);
78370
78371             } else if (option === 'force_local') {
78372                 if (target.type === 'way') {
78373                     target = mergeChildren(target, lodash.uniq(local.nodes), updates, graph);
78374                     graph = updateChildren(updates, graph);
78375                 }
78376                 return graph.replace(target);
78377
78378             } else {
78379                 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
78380                 return graph;  // do nothing
78381             }
78382         }
78383
78384         // merge
78385         if (target.type === 'node') {
78386             target = mergeLocation(remote, target);
78387
78388         } else if (target.type === 'way') {
78389             // pull in any child nodes that may not be present locally..
78390             graph.rebase(remoteGraph.childNodes(remote), [graph], false);
78391             target = mergeNodes(base, remote, target);
78392             target = mergeChildren(target, lodash.union(local.nodes, remote.nodes), updates, graph);
78393
78394         } else if (target.type === 'relation') {
78395             target = mergeMembers(remote, target);
78396         }
78397
78398         target = mergeTags(base, remote, target);
78399
78400         if (!conflicts.length) {
78401             graph = updateChildren(updates, graph).replace(target);
78402         }
78403
78404         return graph;
78405     };
78406
78407
78408     action.withOption = function(opt) {
78409         option = opt;
78410         return action;
78411     };
78412
78413
78414     action.conflicts = function() {
78415         return conflicts;
78416     };
78417
78418
78419     return action;
78420 }
78421
78422 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
78423 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
78424 function actionMove(moveIds, tryDelta, projection, cache) {
78425     var delta = tryDelta;
78426
78427     function vecAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
78428     function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
78429
78430     function setupCache(graph) {
78431         function canMove(nodeId) {
78432             // Allow movement of any node that is in the selectedIDs list..
78433             if (moveIds.indexOf(nodeId) !== -1) return true;
78434
78435             // Allow movement of a vertex where 2 ways meet..
78436             var parents = lodash.map(graph.parentWays(graph.entity(nodeId)), 'id');
78437             if (parents.length < 3) return true;
78438
78439             // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
78440             var parentsMoving = lodash.every(parents, function(id) { return cache.moving[id]; });
78441             if (!parentsMoving) delete cache.moving[nodeId];
78442
78443             return parentsMoving;
78444         }
78445
78446         function cacheEntities(ids) {
78447             ids.forEach(function(id) {
78448                 if (cache.moving[id]) return;
78449                 cache.moving[id] = true;
78450
78451                 var entity = graph.hasEntity(id);
78452                 if (!entity) return;
78453
78454                 if (entity.type === 'node') {
78455                     cache.nodes.push(id);
78456                     cache.startLoc[id] = entity.loc;
78457                 } else if (entity.type === 'way') {
78458                     cache.ways.push(id);
78459                     cacheEntities(entity.nodes);
78460                 } else {
78461                     cacheEntities(entity.members.map(function(member) {
78462                         return member.id;
78463                     }));
78464                 }
78465             });
78466         }
78467
78468         function cacheIntersections(ids) {
78469             function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
78470
78471             ids.forEach(function(id) {
78472                 // consider only intersections with 1 moved and 1 unmoved way.
78473                 var childNodes = graph.childNodes(graph.entity(id));
78474                 childNodes.forEach(function(node) {
78475                     var parents = graph.parentWays(node);
78476                     if (parents.length !== 2) return;
78477
78478                     var moved = graph.entity(id),
78479                         unmoved = lodash.find(parents, function(way) { return !cache.moving[way.id]; });
78480                     if (!unmoved) return;
78481
78482                     // exclude ways that are overly connected..
78483                     if (lodash.intersection(moved.nodes, unmoved.nodes).length > 2) return;
78484
78485                     if (moved.isArea() || unmoved.isArea()) return;
78486
78487                     cache.intersection[node.id] = {
78488                         nodeId: node.id,
78489                         movedId: moved.id,
78490                         unmovedId: unmoved.id,
78491                         movedIsEP: isEndpoint(moved, node.id),
78492                         unmovedIsEP: isEndpoint(unmoved, node.id)
78493                     };
78494                 });
78495             });
78496         }
78497
78498
78499         if (!cache) {
78500             cache = {};
78501         }
78502         if (!cache.ok) {
78503             cache.moving = {};
78504             cache.intersection = {};
78505             cache.replacedVertex = {};
78506             cache.startLoc = {};
78507             cache.nodes = [];
78508             cache.ways = [];
78509
78510             cacheEntities(moveIds);
78511             cacheIntersections(cache.ways);
78512             cache.nodes = lodash.filter(cache.nodes, canMove);
78513
78514             cache.ok = true;
78515         }
78516     }
78517
78518
78519     // Place a vertex where the moved vertex used to be, to preserve way shape..
78520     function replaceMovedVertex(nodeId, wayId, graph, delta) {
78521         var way = graph.entity(wayId),
78522             moved = graph.entity(nodeId),
78523             movedIndex = way.nodes.indexOf(nodeId),
78524             len, prevIndex, nextIndex;
78525
78526         if (way.isClosed()) {
78527             len = way.nodes.length - 1;
78528             prevIndex = (movedIndex + len - 1) % len;
78529             nextIndex = (movedIndex + len + 1) % len;
78530         } else {
78531             len = way.nodes.length;
78532             prevIndex = movedIndex - 1;
78533             nextIndex = movedIndex + 1;
78534         }
78535
78536         var prev = graph.hasEntity(way.nodes[prevIndex]),
78537             next = graph.hasEntity(way.nodes[nextIndex]);
78538
78539         // Don't add orig vertex at endpoint..
78540         if (!prev || !next) return graph;
78541
78542         var key = wayId + '_' + nodeId,
78543             orig = cache.replacedVertex[key];
78544         if (!orig) {
78545             orig = osmNode();
78546             cache.replacedVertex[key] = orig;
78547             cache.startLoc[orig.id] = cache.startLoc[nodeId];
78548         }
78549
78550         var start, end;
78551         if (delta) {
78552             start = projection(cache.startLoc[nodeId]);
78553             end = projection.invert(vecAdd(start, delta));
78554         } else {
78555             end = cache.startLoc[nodeId];
78556         }
78557         orig = orig.move(end);
78558
78559         var angle = Math.abs(geoAngle(orig, prev, projection) -
78560                 geoAngle(orig, next, projection)) * 180 / Math.PI;
78561
78562         // Don't add orig vertex if it would just make a straight line..
78563         if (angle > 175 && angle < 185) return graph;
78564
78565         // Don't add orig vertex if another point is already nearby (within 10m)
78566         if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
78567             geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
78568
78569         // moving forward or backward along way?
78570         var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
78571             p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
78572             d1 = geoPathLength(p1),
78573             d2 = geoPathLength(p2),
78574             insertAt = (d1 < d2) ? movedIndex : nextIndex;
78575
78576         // moving around closed loop?
78577         if (way.isClosed() && insertAt === 0) insertAt = len;
78578
78579         way = way.addNode(orig.id, insertAt);
78580         return graph.replace(orig).replace(way);
78581     }
78582
78583
78584     // Reorder nodes around intersections that have moved..
78585     function unZorroIntersection(intersection, graph) {
78586         var vertex = graph.entity(intersection.nodeId),
78587             way1 = graph.entity(intersection.movedId),
78588             way2 = graph.entity(intersection.unmovedId),
78589             isEP1 = intersection.movedIsEP,
78590             isEP2 = intersection.unmovedIsEP;
78591
78592         // don't move the vertex if it is the endpoint of both ways.
78593         if (isEP1 && isEP2) return graph;
78594
78595         var nodes1 = lodash.without(graph.childNodes(way1), vertex),
78596             nodes2 = lodash.without(graph.childNodes(way2), vertex);
78597
78598         if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
78599         if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
78600
78601         var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection),
78602             edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection),
78603             loc;
78604
78605         // snap vertex to nearest edge (or some point between them)..
78606         if (!isEP1 && !isEP2) {
78607             var epsilon = 1e-4, maxIter = 10;
78608             for (var i = 0; i < maxIter; i++) {
78609                 loc = geoInterp(edge1.loc, edge2.loc, 0.5);
78610                 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
78611                 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
78612                 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
78613             }
78614         } else if (!isEP1) {
78615             loc = edge1.loc;
78616         } else {
78617             loc = edge2.loc;
78618         }
78619
78620         graph = graph.replace(vertex.move(loc));
78621
78622         // if zorro happened, reorder nodes..
78623         if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
78624             way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
78625             graph = graph.replace(way1);
78626         }
78627         if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
78628             way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
78629             graph = graph.replace(way2);
78630         }
78631
78632         return graph;
78633     }
78634
78635
78636     function cleanupIntersections(graph) {
78637         lodash.each(cache.intersection, function(obj) {
78638             graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, delta);
78639             graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
78640             graph = unZorroIntersection(obj, graph);
78641         });
78642
78643         return graph;
78644     }
78645
78646
78647     // check if moving way endpoint can cross an unmoved way, if so limit delta..
78648     function limitDelta(graph) {
78649         lodash.each(cache.intersection, function(obj) {
78650             // Don't limit movement if this is vertex joins 2 endpoints..
78651             if (obj.movedIsEP && obj.unmovedIsEP) return;
78652             // Don't limit movement if this vertex is not an endpoint anyway..
78653             if (!obj.movedIsEP) return;
78654
78655             var node = graph.entity(obj.nodeId),
78656                 start = projection(node.loc),
78657                 end = vecAdd(start, delta),
78658                 movedNodes = graph.childNodes(graph.entity(obj.movedId)),
78659                 movedPath = lodash.map(lodash.map(movedNodes, 'loc'),
78660                     function(loc) { return vecAdd(projection(loc), delta); }),
78661                 unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
78662                 unmovedPath = lodash.map(lodash.map(unmovedNodes, 'loc'), projection),
78663                 hits = geoPathIntersections(movedPath, unmovedPath);
78664
78665             for (var i = 0; i < hits.length; i++) {
78666                 if (lodash.isEqual(hits[i], end)) continue;
78667                 var edge = geoChooseEdge(unmovedNodes, end, projection);
78668                 delta = vecSub(projection(edge.loc), start);
78669             }
78670         });
78671     }
78672
78673
78674     var action = function(graph) {
78675         if (delta[0] === 0 && delta[1] === 0) return graph;
78676
78677         setupCache(graph);
78678
78679         if (!lodash.isEmpty(cache.intersection)) {
78680             limitDelta(graph);
78681         }
78682
78683         lodash.each(cache.nodes, function(id) {
78684             var node = graph.entity(id),
78685                 start = projection(node.loc),
78686                 end = vecAdd(start, delta);
78687             graph = graph.replace(node.move(projection.invert(end)));
78688         });
78689
78690         if (!lodash.isEmpty(cache.intersection)) {
78691             graph = cleanupIntersections(graph);
78692         }
78693
78694         return graph;
78695     };
78696
78697
78698     action.delta = function() {
78699         return delta;
78700     };
78701
78702
78703     return action;
78704 }
78705
78706 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
78707 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
78708 function actionMoveNode(nodeId, loc) {
78709     return function(graph) {
78710         return graph.replace(graph.entity(nodeId).move(loc));
78711     };
78712 }
78713
78714 function actionNoop() {
78715     return function(graph) {
78716         return graph;
78717     };
78718 }
78719
78720 /*
78721  * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
78722  */
78723 function actionOrthogonalize(wayId, projection) {
78724     var threshold = 12, // degrees within right or straight to alter
78725         lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
78726         upperThreshold = Math.cos(threshold * Math.PI / 180);
78727
78728
78729     var action = function(graph, t) {
78730         if (t === null || !isFinite(t)) t = 1;
78731         t = Math.min(Math.max(+t, 0), 1);
78732
78733         var way = graph.entity(wayId),
78734             nodes = graph.childNodes(way),
78735             points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); }),
78736             corner = {i: 0, dotp: 1},
78737             epsilon = 1e-4,
78738             node, loc, score, motions, i, j;
78739
78740         if (points.length === 3) {   // move only one vertex for right triangle
78741             for (i = 0; i < 1000; i++) {
78742                 motions = points.map(calcMotion);
78743                 points[corner.i] = addPoints(points[corner.i], motions[corner.i]);
78744                 score = corner.dotp;
78745                 if (score < epsilon) {
78746                     break;
78747                 }
78748             }
78749
78750             node = graph.entity(nodes[corner.i].id);
78751             loc = projection.invert(points[corner.i]);
78752             graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
78753
78754         } else {
78755             var best,
78756                 originalPoints = lodash.clone(points);
78757             score = Infinity;
78758
78759             for (i = 0; i < 1000; i++) {
78760                 motions = points.map(calcMotion);
78761                 for (j = 0; j < motions.length; j++) {
78762                     points[j] = addPoints(points[j],motions[j]);
78763                 }
78764                 var newScore = squareness(points);
78765                 if (newScore < score) {
78766                     best = lodash.clone(points);
78767                     score = newScore;
78768                 }
78769                 if (score < epsilon) {
78770                     break;
78771                 }
78772             }
78773
78774             points = best;
78775
78776             for (i = 0; i < points.length; i++) {
78777                 // only move the points that actually moved
78778                 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
78779                     loc = projection.invert(points[i]);
78780                     node = graph.entity(nodes[i].id);
78781                     graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
78782                 }
78783             }
78784
78785             // remove empty nodes on straight sections
78786             for (i = 0; t === 1 && i < points.length; i++) {
78787                 node = graph.entity(nodes[i].id);
78788
78789                 if (graph.parentWays(node).length > 1 ||
78790                     graph.parentRelations(node).length ||
78791                     node.hasInterestingTags()) {
78792                     continue;
78793                 }
78794
78795                 var dotp = normalizedDotProduct(i, points);
78796                 if (dotp < -1 + epsilon) {
78797                     graph = actionDeleteNode(node.id)(graph);
78798                 }
78799             }
78800         }
78801
78802         return graph;
78803
78804
78805         function calcMotion(b, i, array) {
78806             var a = array[(i - 1 + array.length) % array.length],
78807                 c = array[(i + 1) % array.length],
78808                 p = subtractPoints(a, b),
78809                 q = subtractPoints(c, b),
78810                 scale, dotp;
78811
78812             scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
78813             p = normalizePoint(p, 1.0);
78814             q = normalizePoint(q, 1.0);
78815
78816             dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
78817
78818             // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
78819             if (array.length > 3) {
78820                 if (dotp < -0.707106781186547) {
78821                     dotp += 1.0;
78822                 }
78823             } else if (dotp && Math.abs(dotp) < corner.dotp) {
78824                 corner.i = i;
78825                 corner.dotp = Math.abs(dotp);
78826             }
78827
78828             return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
78829         }
78830     };
78831
78832
78833     function squareness(points) {
78834         return points.reduce(function(sum, val, i, array) {
78835             var dotp = normalizedDotProduct(i, array);
78836
78837             dotp = filterDotProduct(dotp);
78838             return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
78839         }, 0);
78840     }
78841
78842
78843     function normalizedDotProduct(i, points) {
78844         var a = points[(i - 1 + points.length) % points.length],
78845             b = points[i],
78846             c = points[(i + 1) % points.length],
78847             p = subtractPoints(a, b),
78848             q = subtractPoints(c, b);
78849
78850         p = normalizePoint(p, 1.0);
78851         q = normalizePoint(q, 1.0);
78852
78853         return p[0] * q[0] + p[1] * q[1];
78854     }
78855
78856
78857     function subtractPoints(a, b) {
78858         return [a[0] - b[0], a[1] - b[1]];
78859     }
78860
78861
78862     function addPoints(a, b) {
78863         return [a[0] + b[0], a[1] + b[1]];
78864     }
78865
78866
78867     function normalizePoint(point, scale) {
78868         var vector = [0, 0];
78869         var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
78870         if (length !== 0) {
78871             vector[0] = point[0] / length;
78872             vector[1] = point[1] / length;
78873         }
78874
78875         vector[0] *= scale;
78876         vector[1] *= scale;
78877
78878         return vector;
78879     }
78880
78881
78882     function filterDotProduct(dotp) {
78883         if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
78884             return dotp;
78885         }
78886
78887         return 0;
78888     }
78889
78890
78891     action.disabled = function(graph) {
78892         var way = graph.entity(wayId),
78893             nodes = graph.childNodes(way),
78894             points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); });
78895
78896         if (squareness(points)) {
78897             return false;
78898         }
78899
78900         return 'not_squarish';
78901     };
78902
78903
78904     action.transitionable = true;
78905
78906
78907     return action;
78908 }
78909
78910 // Split a way at the given node.
78911 //
78912 // Optionally, split only the given ways, if multiple ways share
78913 // the given node.
78914 //
78915 // This is the inverse of `iD.actionJoin`.
78916 //
78917 // For testing convenience, accepts an ID to assign to the new way.
78918 // Normally, this will be undefined and the way will automatically
78919 // be assigned a new ID.
78920 //
78921 // Reference:
78922 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
78923 //
78924 function actionSplit(nodeId, newWayIds) {
78925     var wayIds;
78926
78927     // if the way is closed, we need to search for a partner node
78928     // to split the way at.
78929     //
78930     // The following looks for a node that is both far away from
78931     // the initial node in terms of way segment length and nearby
78932     // in terms of beeline-distance. This assures that areas get
78933     // split on the most "natural" points (independent of the number
78934     // of nodes).
78935     // For example: bone-shaped areas get split across their waist
78936     // line, circles across the diameter.
78937     function splitArea(nodes, idxA, graph) {
78938         var lengths = new Array(nodes.length),
78939             length,
78940             i,
78941             best = 0,
78942             idxB;
78943
78944         function wrap(index) {
78945             return utilWrap(index, nodes.length);
78946         }
78947
78948         function dist(nA, nB) {
78949             return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
78950         }
78951
78952         // calculate lengths
78953         length = 0;
78954         for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
78955             length += dist(nodes[i], nodes[wrap(i-1)]);
78956             lengths[i] = length;
78957         }
78958
78959         length = 0;
78960         for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
78961             length += dist(nodes[i], nodes[wrap(i+1)]);
78962             if (length < lengths[i])
78963                 lengths[i] = length;
78964         }
78965
78966         // determine best opposite node to split
78967         for (i = 0; i < nodes.length; i++) {
78968             var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
78969             if (cost > best) {
78970                 idxB = i;
78971                 best = cost;
78972             }
78973         }
78974
78975         return idxB;
78976     }
78977
78978
78979     function split(graph, wayA, newWayId) {
78980         var wayB = osmWay({id: newWayId, tags: wayA.tags}),
78981             nodesA,
78982             nodesB,
78983             isArea = wayA.isArea(),
78984             isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
78985
78986         if (wayA.isClosed()) {
78987             var nodes = wayA.nodes.slice(0, -1),
78988                 idxA = lodash.indexOf(nodes, nodeId),
78989                 idxB = splitArea(nodes, idxA, graph);
78990
78991             if (idxB < idxA) {
78992                 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
78993                 nodesB = nodes.slice(idxB, idxA + 1);
78994             } else {
78995                 nodesA = nodes.slice(idxA, idxB + 1);
78996                 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
78997             }
78998         } else {
78999             var idx = lodash.indexOf(wayA.nodes, nodeId, 1);
79000             nodesA = wayA.nodes.slice(0, idx + 1);
79001             nodesB = wayA.nodes.slice(idx);
79002         }
79003
79004         wayA = wayA.update({nodes: nodesA});
79005         wayB = wayB.update({nodes: nodesB});
79006
79007         graph = graph.replace(wayA);
79008         graph = graph.replace(wayB);
79009
79010         graph.parentRelations(wayA).forEach(function(relation) {
79011             if (relation.isRestriction()) {
79012                 var via = relation.memberByRole('via');
79013                 if (via && wayB.contains(via.id)) {
79014                     relation = relation.replaceMember(wayA, wayB);
79015                     graph = graph.replace(relation);
79016                 }
79017             } else {
79018                 if (relation === isOuter) {
79019                     graph = graph.replace(relation.mergeTags(wayA.tags));
79020                     graph = graph.replace(wayA.update({tags: {}}));
79021                     graph = graph.replace(wayB.update({tags: {}}));
79022                 }
79023
79024                 var member = {
79025                     id: wayB.id,
79026                     type: 'way',
79027                     role: relation.memberById(wayA.id).role
79028                 };
79029
79030                 graph = actionAddMember(relation.id, member)(graph);
79031             }
79032         });
79033
79034         if (!isOuter && isArea) {
79035             var multipolygon = osmRelation({
79036                 tags: lodash.extend({}, wayA.tags, {type: 'multipolygon'}),
79037                 members: [
79038                     {id: wayA.id, role: 'outer', type: 'way'},
79039                     {id: wayB.id, role: 'outer', type: 'way'}
79040                 ]});
79041
79042             graph = graph.replace(multipolygon);
79043             graph = graph.replace(wayA.update({tags: {}}));
79044             graph = graph.replace(wayB.update({tags: {}}));
79045         }
79046
79047         return graph;
79048     }
79049
79050
79051     var action = function(graph) {
79052         var candidates = action.ways(graph);
79053         for (var i = 0; i < candidates.length; i++) {
79054             graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
79055         }
79056         return graph;
79057     };
79058
79059
79060     action.ways = function(graph) {
79061         var node = graph.entity(nodeId),
79062             parents = graph.parentWays(node),
79063             hasLines = lodash.some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
79064
79065         return parents.filter(function(parent) {
79066             if (wayIds && wayIds.indexOf(parent.id) === -1)
79067                 return false;
79068
79069             if (!wayIds && hasLines && parent.geometry(graph) !== 'line')
79070                 return false;
79071
79072             if (parent.isClosed()) {
79073                 return true;
79074             }
79075
79076             for (var i = 1; i < parent.nodes.length - 1; i++) {
79077                 if (parent.nodes[i] === nodeId) {
79078                     return true;
79079                 }
79080             }
79081
79082             return false;
79083         });
79084     };
79085
79086
79087     action.disabled = function(graph) {
79088         var candidates = action.ways(graph);
79089         if (candidates.length === 0 || (wayIds && wayIds.length !== candidates.length))
79090             return 'not_eligible';
79091     };
79092
79093
79094     action.limitWays = function(_) {
79095         if (!arguments.length) return wayIds;
79096         wayIds = _;
79097         return action;
79098     };
79099
79100
79101     return action;
79102 }
79103
79104 // Create a restriction relation for `turn`, which must have the following structure:
79105 //
79106 //     {
79107 //         from: { node: <node ID>, way: <way ID> },
79108 //         via:  { node: <node ID> },
79109 //         to:   { node: <node ID>, way: <way ID> },
79110 //         restriction: <'no_right_turn', 'no_left_turn', etc.>
79111 //     }
79112 //
79113 // This specifies a restriction of type `restriction` when traveling from
79114 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
79115 // (The action does not check that these entities form a valid intersection.)
79116 //
79117 // If `restriction` is not provided, it is automatically determined by
79118 // osmInferRestriction.
79119 //
79120 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
79121 // and `to.node` are used to determine which portion of the split ways become
79122 // members of the restriction.
79123 //
79124 // For testing convenience, accepts an ID to assign to the new relation.
79125 // Normally, this will be undefined and the relation will automatically
79126 // be assigned a new ID.
79127 //
79128 function actionRestrictTurn(turn, projection, restrictionId) {
79129
79130     return function(graph) {
79131         var from = graph.entity(turn.from.way),
79132             via  = graph.entity(turn.via.node),
79133             to   = graph.entity(turn.to.way);
79134
79135         function isClosingNode(way, nodeId) {
79136             return nodeId === way.first() && nodeId === way.last();
79137         }
79138
79139         function split(toOrFrom) {
79140             var newID = toOrFrom.newID || osmWay().id;
79141             graph = actionSplit(via.id, [newID])
79142                 .limitWays([toOrFrom.way])(graph);
79143
79144             var a = graph.entity(newID),
79145                 b = graph.entity(toOrFrom.way);
79146
79147             if (a.nodes.indexOf(toOrFrom.node) !== -1) {
79148                 return [a, b];
79149             } else {
79150                 return [b, a];
79151             }
79152         }
79153
79154         if (!from.affix(via.id) || isClosingNode(from, via.id)) {
79155             if (turn.from.node === turn.to.node) {
79156                 // U-turn
79157                 from = to = split(turn.from)[0];
79158             } else if (turn.from.way === turn.to.way) {
79159                 // Straight-on or circular
79160                 var s = split(turn.from);
79161                 from = s[0];
79162                 to   = s[1];
79163             } else {
79164                 // Other
79165                 from = split(turn.from)[0];
79166             }
79167         }
79168
79169         if (!to.affix(via.id) || isClosingNode(to, via.id)) {
79170             to = split(turn.to)[0];
79171         }
79172
79173         return graph.replace(osmRelation({
79174             id: restrictionId,
79175             tags: {
79176                 type: 'restriction',
79177                 restriction: turn.restriction ||
79178                     osmInferRestriction(
79179                         graph,
79180                         turn.from,
79181                         turn.via,
79182                         turn.to,
79183                         projection)
79184             },
79185             members: [
79186                 {id: from.id, type: 'way',  role: 'from'},
79187                 {id: via.id,  type: 'node', role: 'via'},
79188                 {id: to.id,   type: 'way',  role: 'to'}
79189             ]
79190         }));
79191     };
79192 }
79193
79194 function actionRevert(id) {
79195     var action = function(graph) {
79196         var entity = graph.hasEntity(id),
79197             base = graph.base().entities[id];
79198
79199         if (entity && !base) {    // entity will be removed..
79200             if (entity.type === 'node') {
79201                 graph.parentWays(entity)
79202                     .forEach(function(parent) {
79203                         parent = parent.removeNode(id);
79204                         graph = graph.replace(parent);
79205
79206                         if (parent.isDegenerate()) {
79207                             graph = actionDeleteWay(parent.id)(graph);
79208                         }
79209                     });
79210             }
79211
79212             graph.parentRelations(entity)
79213                 .forEach(function(parent) {
79214                     parent = parent.removeMembersWithID(id);
79215                     graph = graph.replace(parent);
79216
79217                     if (parent.isDegenerate()) {
79218                         graph = actionDeleteRelation(parent.id)(graph);
79219                     }
79220                 });
79221         }
79222
79223         return graph.revert(id);
79224     };
79225
79226     return action;
79227 }
79228
79229 function actionRotate(rotateIds, pivot, angle, projection) {
79230
79231     var action = function(graph) {
79232         return graph.update(function(graph) {
79233             utilGetAllNodes(rotateIds, graph).forEach(function(node) {
79234                 var point = geoRotate([projection(node.loc)], angle, pivot)[0];
79235                 graph = graph.replace(node.move(projection.invert(point)));
79236             });
79237         });
79238     };
79239
79240     return action;
79241 }
79242
79243 /*
79244  * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
79245  */
79246 function actionStraighten(wayId, projection) {
79247
79248     function positionAlongWay(n, s, e) {
79249         return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1])) /
79250                 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
79251     }
79252
79253
79254     var action = function(graph, t) {
79255         if (t === null || !isFinite(t)) t = 1;
79256         t = Math.min(Math.max(+t, 0), 1);
79257
79258         var way = graph.entity(wayId),
79259             nodes = graph.childNodes(way),
79260             points = nodes.map(function(n) { return projection(n.loc); }),
79261             startPoint = points[0],
79262             endPoint = points[points.length-1],
79263             toDelete = [],
79264             i;
79265
79266         for (i = 1; i < points.length-1; i++) {
79267             var node = nodes[i],
79268                 point = points[i];
79269
79270             if (t < 1 || graph.parentWays(node).length > 1 ||
79271                 graph.parentRelations(node).length ||
79272                 node.hasInterestingTags()) {
79273
79274                 var u = positionAlongWay(point, startPoint, endPoint),
79275                     p = [
79276                         startPoint[0] + u * (endPoint[0] - startPoint[0]),
79277                         startPoint[1] + u * (endPoint[1] - startPoint[1])
79278                     ],
79279                     loc2 = projection.invert(p);
79280
79281                 graph = graph.replace(node.move(geoInterp(node.loc, loc2, t)));
79282
79283             } else {
79284                 // safe to delete
79285                 if (toDelete.indexOf(node) === -1) {
79286                     toDelete.push(node);
79287                 }
79288             }
79289         }
79290
79291         for (i = 0; i < toDelete.length; i++) {
79292             graph = actionDeleteNode(toDelete[i].id)(graph);
79293         }
79294
79295         return graph;
79296     };
79297
79298
79299     action.disabled = function(graph) {
79300         // check way isn't too bendy
79301         var way = graph.entity(wayId),
79302             nodes = graph.childNodes(way),
79303             points = nodes.map(function(n) { return projection(n.loc); }),
79304             startPoint = points[0],
79305             endPoint = points[points.length-1],
79306             threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
79307             i;
79308
79309         if (threshold === 0) {
79310             return 'too_bendy';
79311         }
79312
79313         for (i = 1; i < points.length-1; i++) {
79314             var point = points[i],
79315                 u = positionAlongWay(point, startPoint, endPoint),
79316                 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
79317                 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
79318                 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
79319
79320             // to bendy if point is off by 20% of total start/end distance in projected space
79321             if (isNaN(dist) || dist > threshold) {
79322                 return 'too_bendy';
79323             }
79324         }
79325     };
79326
79327
79328     action.transitionable = true;
79329
79330
79331     return action;
79332 }
79333
79334 // Remove the effects of `turn.restriction` on `turn`, which must have the
79335 // following structure:
79336 //
79337 //     {
79338 //         from: { node: <node ID>, way: <way ID> },
79339 //         via:  { node: <node ID> },
79340 //         to:   { node: <node ID>, way: <way ID> },
79341 //         restriction: <relation ID>
79342 //     }
79343 //
79344 // In the simple case, `restriction` is a reference to a `no_*` restriction
79345 // on the turn itself. In this case, it is simply deleted.
79346 //
79347 // The more complex case is where `restriction` references an `only_*`
79348 // restriction on a different turn in the same intersection. In that case,
79349 // that restriction is also deleted, but at the same time restrictions on
79350 // the turns other than the first two are created.
79351 //
79352 function actionUnrestrictTurn(turn) {
79353     return function(graph) {
79354         return actionDeleteRelation(turn.restriction)(graph);
79355     };
79356 }
79357
79358 /* Reflect the given area around its axis of symmetry */
79359 function actionReflect(reflectIds, projection$$1) {
79360     var useLongAxis = true;
79361
79362
79363     // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
79364     // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
79365     function getSmallestSurroundingRectangle(graph, nodes) {
79366         var points = nodes.map(function(n) { return projection$$1(n.loc); }),
79367             hull = d3polygonHull(points),
79368             centroid = d3polygonCentroid(hull),
79369             minArea = Infinity,
79370             ssrExtent = [],
79371             ssrAngle = 0,
79372             c1 = hull[0];
79373
79374         for (var i = 0; i < hull.length - 1; i++) {
79375             var c2 = hull[i + 1],
79376                 angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]),
79377                 poly = geoRotate(hull, -angle, centroid),
79378                 extent$$1 = poly.reduce(function(extent$$1, point) {
79379                         return extent$$1.extend(geoExtent$$1(point));
79380                     }, geoExtent$$1()),
79381                 area$$1 = extent$$1.area();
79382
79383             if (area$$1 < minArea) {
79384                 minArea = area$$1;
79385                 ssrExtent = extent$$1;
79386                 ssrAngle = angle;
79387             }
79388             c1 = c2;
79389         }
79390
79391         return {
79392             poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
79393             angle: ssrAngle
79394         };
79395     }
79396
79397
79398     var action = function(graph, t) {
79399         if (t === null || !isFinite(t)) t = 1;
79400         t = Math.min(Math.max(+t, 0), 1);
79401
79402         var nodes = utilGetAllNodes(reflectIds, graph),
79403             ssr = getSmallestSurroundingRectangle(graph, nodes);
79404
79405         // Choose line pq = axis of symmetry.
79406         // The shape's surrounding rectangle has 2 axes of symmetry.
79407         // Reflect across the longer axis by default.
79408         var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ],
79409             q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ],
79410             p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ],
79411             q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
79412             p, q;
79413
79414         var isLong = (geoEuclideanDistance(p1, q1) > geoEuclideanDistance(p2, q2));
79415         if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
79416             p = p1;
79417             q = q1;
79418         } else {
79419             p = p2;
79420             q = q2;
79421         }
79422
79423         // reflect c across pq
79424         // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
79425         var dx = q[0] - p[0];
79426         var dy = q[1] - p[1];
79427         var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
79428         var b = 2 * dx * dy / (dx * dx + dy * dy);
79429         for (var i = 0; i < nodes.length; i++) {
79430             var node = nodes[i];
79431             var c = projection$$1(node.loc);
79432             var c2 = [
79433                 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
79434                 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
79435             ];
79436             var loc2 = projection$$1.invert(c2);
79437             node = node.move(geoInterp(node.loc, loc2, t));
79438             graph = graph.replace(node);
79439         }
79440
79441         return graph;
79442     };
79443
79444
79445     action.useLongAxis = function(_) {
79446         if (!arguments.length) return useLongAxis;
79447         useLongAxis = _;
79448         return action;
79449     };
79450
79451
79452     action.transitionable = true;
79453
79454
79455     return action;
79456 }
79457
79458
79459
79460 var index$17 = Object.freeze({
79461         d3combobox: d3combobox,
79462         d3geoTile: d3geoTile,
79463         d3keybinding: d3keybinding
79464 });
79465
79466 /* export some legacy symbols: */
79467 var Connection = services.osm;
79468 var debug = false;
79469
79470
79471
79472
79473 var iD = Object.freeze({
79474         Connection: Connection,
79475         debug: debug,
79476         d3: index$2,
79477         _: lodash$1,
79478         lib: index$17,
79479         Context: coreContext,
79480         setAreaKeys: setAreaKeys,
79481         Difference: coreDifference,
79482         Graph: coreGraph$$1,
79483         History: coreHistory,
79484         Tree: coreTree,
79485         Entity: osmEntity$$1,
79486         Node: osmNode,
79487         Relation: osmRelation,
79488         Way: osmWay,
79489         BackgroundSource: rendererBackgroundSource,
79490         Background: rendererBackground,
79491         Features: rendererFeatures,
79492         Map: rendererMap,
79493         TileLayer: rendererTileLayer,
79494         Detect: utilDetect,
79495         uiPreset: uiPresetEditor,
79496         actionAddEntity: actionAddEntity,
79497         actionAddMember: actionAddMember,
79498         actionAddMidpoint: actionAddMidpoint,
79499         actionAddVertex: actionAddVertex,
79500         actionChangeMember: actionChangeMember,
79501         actionChangePreset: actionChangePreset,
79502         actionChangeTags: actionChangeTags,
79503         actionCircularize: actionCircularize,
79504         actionConnect: actionConnect,
79505         actionCopyEntities: actionCopyEntities,
79506         actionDeleteMember: actionDeleteMember,
79507         actionDeleteMultiple: actionDeleteMultiple,
79508         actionDeleteNode: actionDeleteNode,
79509         actionDeleteRelation: actionDeleteRelation,
79510         actionDeleteWay: actionDeleteWay,
79511         actionDeprecateTags: actionDeprecateTags,
79512         actionDiscardTags: actionDiscardTags,
79513         actionDisconnect: actionDisconnect,
79514         actionJoin: actionJoin,
79515         actionMerge: actionMerge,
79516         actionMergePolygon: actionMergePolygon,
79517         actionMergeRemoteChanges: actionMergeRemoteChanges,
79518         actionMove: actionMove,
79519         actionMoveNode: actionMoveNode,
79520         actionNoop: actionNoop,
79521         actionOrthogonalize: actionOrthogonalize,
79522         actionRestrictTurn: actionRestrictTurn,
79523         actionReverse: actionReverse,
79524         actionRevert: actionRevert,
79525         actionRotate: actionRotate,
79526         actionSplit: actionSplit,
79527         actionStraighten: actionStraighten,
79528         actionUnrestrictTurn: actionUnrestrictTurn,
79529         actionReflect: actionReflect,
79530         behaviorAddWay: behaviorAddWay,
79531         behaviorBreathe: behaviorBreathe,
79532         behaviorCopy: behaviorCopy,
79533         behaviorDrag: behaviorDrag,
79534         behaviorDrawWay: behaviorDrawWay,
79535         behaviorDraw: behaviorDraw,
79536         behaviorEdit: behaviorEdit,
79537         behaviorHash: behaviorHash,
79538         behaviorHover: behaviorHover,
79539         behaviorLasso: behaviorLasso,
79540         behaviorOperation: behaviorOperation,
79541         behaviorPaste: behaviorPaste,
79542         behaviorSelect: behaviorSelect,
79543         behaviorTail: behaviorTail,
79544         coreContext: coreContext,
79545         coreDifference: coreDifference,
79546         coreGraph: coreGraph$$1,
79547         coreHistory: coreHistory,
79548         coreTree: coreTree,
79549         dataFeatureIcons: dataFeatureIcons,
79550         data: data,
79551         dataWikipedia: dataWikipedia,
79552         dataSuggestions: dataSuggestions,
79553         dataAddressFormats: dataAddressFormats,
79554         dataDeprecated: dataDeprecated,
79555         dataDiscarded: dataDiscarded,
79556         dataLocales: dataLocales,
79557         dataPhoneFormats: dataPhoneFormats,
79558         dataShortcuts: dataShortcuts,
79559         dataImperial: dataImperial,
79560         dataDriveLeft: dataDriveLeft,
79561         dataEn: en,
79562         geoAngle: geoAngle,
79563         geoChooseEdge: geoChooseEdge,
79564         geoCross: geoCross,
79565         geoEdgeEqual: geoEdgeEqual,
79566         geoEuclideanDistance: geoEuclideanDistance,
79567         geoExtent: geoExtent$$1,
79568         geoInterp: geoInterp,
79569         geoRawMercator: geoRawMercator,
79570         geoRoundCoords: geoRoundCoords,
79571         geoRotate: geoRotate,
79572         geoLatToMeters: geoLatToMeters,
79573         geoLineIntersection: geoLineIntersection,
79574         geoLonToMeters: geoLonToMeters,
79575         geoMetersToLat: geoMetersToLat,
79576         geoMetersToLon: geoMetersToLon,
79577         geoMetersToOffset: geoMetersToOffset,
79578         geoOffsetToMeters: geoOffsetToMeters,
79579         geoPathIntersections: geoPathIntersections,
79580         geoPathLength: geoPathLength,
79581         geoPointInPolygon: geoPointInPolygon,
79582         geoPolygonContainsPolygon: geoPolygonContainsPolygon,
79583         geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
79584         geoSphericalDistance: geoSphericalDistance,
79585         modeAddArea: modeAddArea$$1,
79586         modeAddLine: modeAddLine$$1,
79587         modeAddPoint: modeAddPoint$$1,
79588         modeBrowse: modeBrowse,
79589         modeDragNode: modeDragNode$$1,
79590         modeDrawArea: modeDrawArea,
79591         modeDrawLine: modeDrawLine,
79592         modeMove: modeMove$$1,
79593         modeRotate: modeRotate$$1,
79594         modeSave: modeSave$$1,
79595         modeSelect: modeSelect,
79596         operationCircularize: operationCircularize,
79597         operationContinue: operationContinue,
79598         operationDelete: operationDelete,
79599         operationDisconnect: operationDisconnect,
79600         operationMerge: operationMerge,
79601         operationMove: operationMove,
79602         operationOrthogonalize: operationOrthogonalize,
79603         operationReflectShort: operationReflectShort,
79604         operationReflectLong: operationReflectLong,
79605         operationReverse: operationReverse,
79606         operationRotate: operationRotate,
79607         operationSplit: operationSplit,
79608         operationStraighten: operationStraighten,
79609         osmChangeset: osmChangeset,
79610         osmEntity: osmEntity$$1,
79611         osmNode: osmNode,
79612         osmRelation: osmRelation,
79613         osmWay: osmWay,
79614         osmIntersection: osmIntersection,
79615         osmTurn: osmTurn,
79616         osmInferRestriction: osmInferRestriction,
79617         osmLanes: osmLanes,
79618         osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
79619         osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
79620         osmJoinWays: osmJoinWays,
79621         osmOneWayTags: osmOneWayTags,
79622         osmPavedTags: osmPavedTags,
79623         osmIsInterestingTag: osmIsInterestingTag,
79624         presetCategory: presetCategory,
79625         presetCollection: presetCollection,
79626         presetField: presetField,
79627         presetPreset: presetPreset,
79628         presetIndex: presetIndex,
79629         rendererBackgroundSource: rendererBackgroundSource,
79630         rendererBackground: rendererBackground,
79631         rendererFeatures: rendererFeatures,
79632         rendererMap: rendererMap,
79633         rendererTileLayer: rendererTileLayer,
79634         services: services,
79635         serviceMapillary: serviceMapillary,
79636         serviceNominatim: serviceNominatim,
79637         serviceOsm: serviceOsm,
79638         serviceTaginfo: serviceTaginfo,
79639         serviceWikidata: serviceWikidata,
79640         serviceWikipedia: serviceWikipedia,
79641         svgAreas: svgAreas$$1,
79642         svgDebug: svgDebug,
79643         svgDefs: svgDefs,
79644         svgGpx: svgGpx,
79645         svgIcon: svgIcon,
79646         svgLabels: svgLabels,
79647         svgLayers: svgLayers,
79648         svgLines: svgLines$$1,
79649         svgMapillaryImages: svgMapillaryImages,
79650         svgMapillarySigns: svgMapillarySigns,
79651         svgMidpoints: svgMidpoints$$1,
79652         svgOneWaySegments: svgOneWaySegments,
79653         svgOsm: svgOsm,
79654         svgPath: svgPath,
79655         svgPointTransform: svgPointTransform,
79656         svgPoints: svgPoints$$1,
79657         svgRelationMemberTags: svgRelationMemberTags,
79658         svgTagClasses: svgTagClasses,
79659         svgTurns: svgTurns,
79660         svgVertices: svgVertices$$1,
79661         uiFields: uiFields,
79662         uiFieldDefaultCheck: uiFieldCheck,
79663         uiFieldOnewayCheck: uiFieldCheck,
79664         uiFieldCheck: uiFieldCheck,
79665         uiFieldMultiCombo: uiFieldCombo,
79666         uiFieldNetworkCombo: uiFieldCombo,
79667         uiFieldSemiCombo: uiFieldCombo,
79668         uiFieldTypeCombo: uiFieldCombo,
79669         uiFieldCombo: uiFieldCombo,
79670         uiFieldUrl: uiFieldText,
79671         uiFieldNumber: uiFieldText,
79672         uiFieldTel: uiFieldText,
79673         uiFieldEmail: uiFieldText,
79674         uiFieldText: uiFieldText,
79675         uiFieldAccess: uiFieldAccess,
79676         uiFieldAddress: uiFieldAddress,
79677         uiFieldCycleway: uiFieldCycleway,
79678         uiFieldLanes: uiFieldLanes,
79679         uiFieldLocalized: uiFieldLocalized,
79680         uiFieldMaxspeed: uiFieldMaxspeed,
79681         uiFieldStructureRadio: uiFieldRadio,
79682         uiFieldRadio: uiFieldRadio,
79683         uiFieldRestrictions: uiFieldRestrictions,
79684         uiFieldTextarea: uiFieldTextarea,
79685         uiFieldWikipedia: uiFieldWikipedia,
79686         uiIntro: uiIntro,
79687         uiInfoPanels: uiInfoPanels,
79688         uiPanelBackground: uiPanelBackground,
79689         uiPanelHistory: uiPanelHistory,
79690         uiPanelLocation: uiPanelLocation,
79691         uiPanelMeasurement: uiPanelMeasurement,
79692         uiInit: uiInit,
79693         uiAccount: uiAccount,
79694         uiAttribution: uiAttribution,
79695         uiBackground: uiBackground,
79696         uiChangesetEditor: uiChangesetEditor,
79697         uiCmd: uiCmd,
79698         uiCommit: uiCommit,
79699         uiCommitChanges: uiCommitChanges,
79700         uiCommitWarnings: uiCommitWarnings,
79701         uiConfirm: uiConfirm,
79702         uiConflicts: uiConflicts,
79703         uiContributors: uiContributors,
79704         uiCurtain: uiCurtain,
79705         uiDisclosure: uiDisclosure,
79706         uiEditMenu: uiEditMenu,
79707         uiEntityEditor: uiEntityEditor,
79708         uiFeatureInfo: uiFeatureInfo,
79709         uiFeatureList: uiFeatureList,
79710         uiField: uiField,
79711         uiFlash: uiFlash,
79712         uiFormFields: uiFormFields,
79713         uiFullScreen: uiFullScreen,
79714         uiGeolocate: uiGeolocate,
79715         uiHelp: uiHelp,
79716         uiInfo: uiInfo,
79717         uiInspector: uiInspector,
79718         uiLasso: uiLasso,
79719         uiLoading: uiLoading,
79720         uiMapData: uiMapData,
79721         uiMapInMap: uiMapInMap,
79722         uiModal: uiModal,
79723         uiModes: uiModes,
79724         uiNotice: uiNotice,
79725         uiPresetEditor: uiPresetEditor,
79726         uiPresetIcon: uiPresetIcon,
79727         uiPresetList: uiPresetList,
79728         uiRadialMenu: uiRadialMenu,
79729         uiRawMemberEditor: uiRawMemberEditor,
79730         uiRawMembershipEditor: uiRawMembershipEditor,
79731         uiRawTagEditor: uiRawTagEditor,
79732         uiRestore: uiRestore,
79733         uiSave: uiSave,
79734         uiScale: uiScale,
79735         uiSelectionList: uiSelectionList,
79736         uiSidebar: uiSidebar,
79737         uiSourceSwitch: uiSourceSwitch,
79738         uiSpinner: uiSpinner,
79739         uiSplash: uiSplash,
79740         uiStatus: uiStatus,
79741         uiSuccess: uiSuccess,
79742         uiTagReference: uiTagReference,
79743         uiToggle: uiToggle,
79744         uiTooltipHtml: uiTooltipHtml,
79745         uiUndoRedo: uiUndoRedo,
79746         uiVersion: uiVersion,
79747         uiViewOnOSM: uiViewOnOSM,
79748         uiZoom: uiZoom,
79749         utilAsyncMap: utilAsyncMap,
79750         utilDisplayName: utilDisplayName,
79751         utilDisplayNameForPath: utilDisplayNameForPath,
79752         utilDisplayType: utilDisplayType,
79753         utilEditDistance: utilEditDistance,
79754         utilEntitySelector: utilEntitySelector,
79755         utilEntityOrMemberSelector: utilEntityOrMemberSelector,
79756         utilFastMouse: utilFastMouse,
79757         utilFunctor: utilFunctor,
79758         utilGetAllNodes: utilGetAllNodes,
79759         utilGetPrototypeOf: utilGetPrototypeOf,
79760         utilGetSetValue: utilGetSetValue,
79761         utilNoAuto: utilNoAuto,
79762         utilPrefixCSSProperty: utilPrefixCSSProperty,
79763         utilPrefixDOMProperty: utilPrefixDOMProperty,
79764         utilQsString: utilQsString,
79765         utilRebind: utilRebind,
79766         utilSetTransform: utilSetTransform,
79767         utilSessionMutex: utilSessionMutex,
79768         utilStringQs: utilStringQs,
79769         utilSuggestNames: utilSuggestNames,
79770         utilTagText: utilTagText,
79771         utilTriggerEvent: utilTriggerEvent,
79772         utilWrap: utilWrap,
79773         utilIdleWorker: utilIdleWorker,
79774         utilCallWhenIdle: utilCallWhenIdle,
79775         d3combobox: d3combobox,
79776         d3geoTile: d3geoTile,
79777         d3keybinding: d3keybinding,
79778         validationDeprecatedTag: validationDeprecatedTag,
79779         validationDisconnectedHighway: validationDisconnectedHighway,
79780         validationManyDeletions: validationManyDeletions,
79781         validationMissingTag: validationMissingTag,
79782         validationOldMultipolygon: validationOldMultipolygon,
79783         validationTagSuggestsArea: validationTagSuggestsArea
79784 });
79785
79786 window.iD = iD;
79787
79788 }());
79789 //# sourceMappingURL=iD.js.map